diff --git a/Part2-API-Schemas/openapi.yaml b/Part2-API-Schemas/openapi.yaml index 1783b4dc..8a48fd8d 100644 --- a/Part2-API-Schemas/openapi.yaml +++ b/Part2-API-Schemas/openapi.yaml @@ -629,6 +629,10 @@ components: type: string pattern: >- ^((?:\$aas#(?:idShort|id|assetInformation\.assetKind|assetInformation\.assetType|assetInformation\.globalAssetId|assetInformation\.(?:specificAssetIds(\[[0-9]*\])(?:\.(?:name|value|externalSubjectId(?:\.type|\.keys\[\d*\](?:\.(?:type|value))?)?)?)|submodels\.(?:type|keys\[\d*\](?:\.(?:type|value))?))|submodels\.(type|keys\[\d*\](?:\.(type|value))?)))|(?:\$sm#(?:semanticId(?:\.type|\.keys\[\d*\](?:\.(type|value))?)?|idShort|id))|(?:\$sme(?:\.[a-zA-Z][a-zA-Z0-9_]*(\[[0-9]*\])?(?:\.[a-zA-Z][a-zA-Z0-9_]*(\[[0-9]*\])?)*)?#(?:semanticId(?:\.type|\.keys\[\d*\](?:\.(type|value))?)?|idShort|value|valueType|language))|(?:\$cd#(?:idShort|id))|(?:\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds(\[[0-9]*\])?(?:\.(name|value|externalSubjectId(?:\.type|\.keys\[\d*\](?:\.(type|value))?)?)?)|endpoints(\[[0-9]*\])\.(interface|protocolinformation\.href)|submodelDescriptors(\[[0-9]*\])\.(semanticId(?:\.type|\.keys\[\d*\](?:\.(type|value))?)?|idShort|id|endpoints(\[[0-9]*\])\.(interface|protocolinformation\.href))))|(?:\$smdesc#(?:semanticId(?:\.type|\.keys\[\d*\](?:\.(type|value))?)?|idShort|id|endpoints(\[[0-9]*\])\.(interface|protocolinformation\.href))))$ + fragmentStringPattern: + type: string + pattern: >- + ^(?:\$aas#(?:idShort|assetInformation\.assetType|assetInformation\.globalAssetId|assetInformation\.specificAssetIds\[\d*\](?:\.externalSubjectId(?:\.keys\[\d*\])?)?|submodels|submodels\.keys\[\d*\])|(?:\$sm#(?:semanticId(?:\.keys\[\d*\])?|idShort|id))|(?:\$sme(?:\.(?:[a-zA-Z](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?(?:\[\d*\])*)*)?(?:#(?:semanticId(?:\.keys\[\d*\])?|idShort|value|valueType|language))?)|(?:\$cd#idShort)|(?:\$aasdesc#(?:idShort|assetKind|assetType|globalAssetId|specificAssetIds\[\d*\](?:\.externalSubjectId(?:\.keys\[\d*\])?)?|endpoints\[\d*\]|submodelDescriptors\[\d*\]|submodelDescriptors\[\d*\]\.(?:semanticId(?:\.keys\[\d*\])?|idShort|endpoints\[\d*\])))|(?:\$smdesc#(?:semanticId(?:\.keys\[\d*\])?|idShort|endpoints\[\d*\])))$ MultiLanguagePropertyMetadata: allOf: - $ref: "#/components/schemas/SubmodelElementAttributes" @@ -776,6 +780,19 @@ components: required: - href type: object + QueryFilter: + type: object + properties: + $fragment: + description: Field identifier fragment the filter applies to (FieldIdentifierFragment in the BNF). + $ref: '#/components/schemas/fragmentStringPattern' + $condition: + description: Logical expression to be applied for this field identifier fragment. + $ref: '#/components/schemas/logicalExpression' + required: + - $fragment + - $condition + additionalProperties: false Query: type: object properties: @@ -784,6 +801,13 @@ components: pattern: ^id$ $condition: $ref: '#/components/schemas/logicalExpression' + $filters: + description: >- + Additional filters scoped to specific field identifier fragments, corresponding to + repeated "$filter " clauses in the BNF. + type: array + items: + $ref: '#/components/schemas/QueryFilter' required: - $condition additionalProperties: false diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc b/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc index fb4607d5..eeeb2f5c 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc @@ -14,7 +14,7 @@ Note: Changes in Metamodel (IDTA-01001) will not be listed here, although they h Major Changes: -* ... +* new: Enhanced the FieldIdentifier Fragment Definition from just plain string to a BNF specification. Extended the query language and security with field-based filters (`$filters` & `FILTERS` clauses) using field identifier fragments, and aligned the OpenAPI schemas and JSON Schema for queries and security rules accordingly. Addition does not introduce breaking changes because it only adds new optional field (https://github.com/admin-shell-io/aas-specs-api/issues/517[#517]) Minor Changes: 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..36b934ce 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,26 +1,15 @@ { - "$schema": "../../query-json-schema.json", - "select": "id", - "filter": { - "$and":[ - { - "$eq": [ - { - "strModel": "$sm.semanticId.keys.value" - }, - { - "strVal": "https://example.org/value" - } - ] - }, - {} - ] - }, - "option": { - "sort": { - "id": "asc" - }, - "limit": 10, - "offset": 0 + "Query": { + "$select": "id", + "$condition": { + "$eq": [ + { + "$field": "$sm#semanticId.keys[].value" + }, + { + "$strVal": "https://example.org/value" + } + ] + } } } \ No newline at end of file diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/json-grammar.txt b/documentation/IDTA-01002-3/modules/ROOT/pages/json-grammar.txt index b79ae9d6..a7771627 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/json-grammar.txt +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/json-grammar.txt @@ -1,169 +1,163 @@ - ::= ( | ) - ::= "{" "\"Query\":" "{" "\"$condition\":" ("," "\"$select\":" "id" )? "}" "}" + ::= "{" "\"Query\":" "{" + "\"$condition\":" + ( "," "\"$select\":" "\"id\"" )? + ( "," "\"$filters\":" )? + "}" "}" + + ::= "[" ( ( "," )* )? "]" + + ::= "{" + "\"$fragment\":" + "," "\"$condition\":" + "}" ::= "{" - ( - "\"$and\":" - | "\"$or\":" - | "\"$not\":" - | "\"$match\":" - | "\"$eq\":" - | "\"$ne\":" - | "\"$gt\":" - | "\"$ge\":" - | "\"$lt\":" - | "\"$le\":" - | "\"$contains\":" - | "\"$starts_with\":" - | "\"$ends_with\":" - | "\"$regex\":" - | "\"$boolean\":" - ) - "}" + ( + "\"$and\":" + | "\"$or\":" + | "\"$not\":" + | "\"$match\":" + | "\"$eq\":" + | "\"$ne\":" + | "\"$gt\":" + | "\"$ge\":" + | "\"$lt\":" + | "\"$le\":" + | "\"$contains\":" + | "\"$starts-with\":" + | "\"$ends-with\":" + | "\"$regex\":" + | "\"$boolean\":" + ) + "}" ::= "{" - ( - "\"$match\":" - | "\"$eq\":" - | "\"$ne\":" - | "\"$gt\":" - | "\"$ge\":" - | "\"$lt\":" - | "\"$le\":" - | "\"$contains\":" - | "\"$starts_with\":" - | "\"$ends_with\":" - | "\"$regex\":" - | "\"$boolean\":" - ) - "}" + ( + "\"$match\":" + | "\"$eq\":" + | "\"$ne\":" + | "\"$gt\":" + | "\"$ge\":" + | "\"$lt\":" + | "\"$le\":" + | "\"$contains\":" + | "\"$starts-with\":" + | "\"$ends-with\":" + | "\"$regex\":" + | "\"$boolean\":" + ) + "}" ::= "[" "," "]" - ::= "[" "," "]" - - ::= "[" ( "," )* "]" - ::= "[" ( "," )* "]" + ::= "[" ( "," )* "]" + ::= "[" ( "," )* "]" ::= "{" - ( - "\"$field\":" - | "\"$strVal\":" - | "\"$attribute\":" - | "\"$numVal\":" - | "\"$hexVal\":" - | "\"$dateTimeVal\":" - | "\"$timeVal\":" - | "\"$boolean\":" - | "\"$numCast\":" - | "\"$hexCast\":" - | "\"$boolCast\":" - | "\"$dateTimeCast\":" - | "\"$timeCast\":" - | "\"$dayOfWeek\":" - | "\"$dayOfMonth\":" - | "\"$month\":" - | "\"$year\":" - ) - "}" - - - ::= ( - "\"$strCast\":" - | "\"$numCast\":" - | "\"$hexCast\":" - | "\"$boolCast\":" - | "\"$dateTimeCast\":" - | "\"$timeCast\":" - ) + ( + "\"$field\":" + | "\"$strVal\":" + | "\"$attribute\":" + | "\"$numVal\":" + | "\"$hexVal\":" + | "\"$dateTimeVal\":" + | "\"$timeVal\":" + | "\"$boolean\":" + | "\"$strCast\":" + | "\"$numCast\":" + | "\"$hexCast\":" + | "\"$boolCast\":" + | "\"$dateTimeCast\":" + | "\"$timeCast\":" + | "\"$dayOfWeek\":" ( | ) + | "\"$dayOfMonth\":" ( | ) + | "\"$month\":" ( | ) + | "\"$year\":" ( | ) + ) + "}" ::= "{" - ( - "\"$field\":" - | "\"$strVal\":" - | "\"$strCast\":" - | "\"$attribute\":" - ) - "}" + ( + "\"$field\":" + | "\"$strVal\":" + | "\"$attribute\":" + | "\"$strCast\":" + ) + "}" ::= "{" "\"AllAccessPermissionRules\":" "{" - ("\"DEFATTRIBUTES\":" "," )? - ("\"DEFACLS\":" "," )? - ("\"DEFOBJECTS\":" "," )? - ("\"DEFFORMULAS\":" "," )? - "\"rules\":" - "}" "}" - - ::= "[" ("," )* "]" - + ( "\"DEFATTRIBUTES\":" "," )? + ( "\"DEFACLS\":" "," )? + ( "\"DEFOBJECTS\":" "," )? + ( "\"DEFFORMULAS\":" "," )? + "\"rules\":" + "}" "}" + + ::= "[" ( "," )* "]" ::= "{" - "\"name\":" - "," "\"attributes\":" - "}" - - ::= "[" ("," )* "]" + "\"name\":" + "," "\"attributes\":" + "}" + ::= "[" ( "," )* "]" ::= "{" - "\"name\":" - "," "\"acl\":" - "}" - - ::= "[" ("," )* "]" + "\"name\":" + "," "\"acl\":" + "}" + ::= "[" ( "," )* "]" ::= "{" - "\"name\":" - "," ( - "\"objects\":" - | "\"USEOBJECTS\":" - ) - "}" - - ::= "[" ("," )* "]" + "\"name\":" + "," ( "\"objects\":" + | "\"USEOBJECTS\":" ) + "}" + ::= "[" ( "," )* "]" ::= "{" - "\"name\":" - "," "\"formula\":" - "}" + "\"name\":" + "," "\"formula\":" + "}" ::= "[" ( "," )* "]" ::= "{" - ( ( "\"ACL\":" ) - | ( "\"USEACL\":" ) ) - ( ( "," "\"OBJECTS\":" ) - | ( "," "\"USEOBJECTS\":" ) ) - ( ( "," "\"FORMULA\":" ) - | ("," "\"USEFORMULA\":" ) ) - ("," "\"FRAGMENT\":" )? - ( ( "," "\"FILTER\":" ) - | ("," "\"USEFILTER\":" ) )? - "}" + ( "\"ACL\":" + | "\"USEACL\":" ) + ( "," "\"OBJECTS\":" + | "," "\"USEOBJECTS\":" ) + ( "," "\"FORMULA\":" + | "," "\"USEFORMULA\":" ) + ( "," "\"FILTER\":" )? + ( "," "\"FILTERLIST\":" )? + "}" + + ::= "[" ( "," )* "]" + ::= "{" + "\"FRAGMENT\":" + "," ( "\"CONDITION\":" + | "\"USEFORMULA\":" ) + "}" ::= "{" - ( ( "\"ATTRIBUTES\":" ) - | ( "\"USEATTRIBUTES\":" ) ) - "," "\"RIGHTS\":" - "," "\"ACCESS\":" - "}" - - ::= "[" ("," )* "]" + ( "\"ATTRIBUTES\":" + | "\"USEATTRIBUTES\":" ) + "," "\"RIGHTS\":" + "," "\"ACCESS\":" + "}" + ::= "[" ( "," )* "]" ::= "{" - ( - "\"CLAIM\":" - | "\"GLOBAL\":" - | "\"REFERENCE\":" - ) - "}" + ( "\"CLAIM\":" + | "\"GLOBAL\":" + | "\"REFERENCE\":" ) + "}" ::= "[" ( "," )* "]" + ::= "[" ( "," )* "]" - ::= "[" ("," )* "]" - - ::= "[" ("," )* "]" - + ::= "[" ( "," )* "]" ::= "{" ( "\"ROUTE\":" @@ -174,28 +168,11 @@ ) "}" - ::= "[" ("," )* "]" - - ::= ( - "\"CREATE\"" - | "\"READ\"" - | "\"UPDATE\"" - | "\"DELETE\"" - | "\"EXECUTE\"" - | "\"VIEW\"" - | "\"ALL\"" - ) - - ::= ("\"ALLOW\"" | "\"DISABLED\"") - - ::= ( - "\"LOCALNOW\"" - | "\"UTCNOW\"" - | "\"CLIENTNOW\"" - | "\"ANONYMOUS\"" - ) - + ::= "[" ( "," )* "]" + ::= ( "\"CREATE\"" | "\"READ\"" | "\"UPDATE\"" | "\"DELETE\"" | "\"EXECUTE\"" | "\"VIEW\"" | "\"ALL\"" ) + ::= ( "\"ALLOW\"" | "\"DISABLED\"" ) + ::= ( "\"LOCALNOW\"" | "\"UTCNOW\"" | "\"CLIENTNOW\"" | "\"ANONYMOUS\"" ) ::= ("true" | "false") ::= "\"" "\"" @@ -226,19 +203,45 @@ ::= "true" | "false" ::= "\"" "\"" + ::= "\"" "\"" + ::= | | | | | + ::= | | | | | + ::= "$aas#" ( "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels." ) ::= "$sm#" ( | "idShort" | "id" ) ::= "$sme" ( "." )? "#" ( | "idShort" | "value" | "valueType" | "language" ) - ::= "$cd#" ( "idShort" | "id" ) - ::= "$aasdesc#" ( "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | | "endpoints" ( "[" ( [0-9]* ) "]" )? "." | "submodelDescriptors" ( "[" ( [0-9]* ) "]" )? "." ) + ::= "$cd#" ( "idShort" | "id" ) + ::= "$aasdesc#" ( "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | | | "." ) ::= "$smdesc#" - ::= ( | "idShort" | "id" | "endpoints" ( "[" ( [0-9]* ) "]" )? "." ) - ::= "interface" | "protocolinformation.href" - ::= ( "type" | "keys" ( "[" ( [0-9]* ) "]" )? ( ".type" | ".value" ) ) + + ::= "$aas#" ( "idShort" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels" | "submodels." ) + ::= "$sm#" ( | "idShort" | "id" ) + ::= "$sme" ( "." )? ( "#" ( | "idShort" | "value" | "valueType" | "language" ) )? + ::= "$cd#idShort" + ::= "$aasdesc#" ( "idShort" | "description" | "displayName" | "extension" | "administration" | "assetKind" | "assetType" | "globalAssetId" | | | | "." ) + ::= "$smdesc#" + + ::= "submodelDescriptors[" ( [0-9]* ) "]" + ::= ( | "idShort" | "id" | ) + ::= ( | "idShort" | "description" | "displayName" | "extension" | "administration" | "supplementalSemanticId" | ) + + ::= "endpoints[" ( [0-9]* ) "]" ( ".interface" | ".protocolinformation.href" ) + ::= "endpoints[" ( [0-9]* ) "]" + + ::= ( "type" | "keys[" ( [0-9]* ) "]" ( ".type" | ".value" ) ) + ::= "keys[" ( [0-9]* ) "]" + ::= ( "semanticId" | "semanticId." ) - ::= ( "specificAssetIds" ( "[" ( [0-9]* ) "]" )? ( ".name" | ".value" | ".externalSubjectId" | ".externalSubjectId." ) ) - ::= ( ("[" ( [0-9]* ) "]" )? ( "." )* ) - ::= ( ( [a-z] | [A-Z] ) ( [a-z] | [A-Z] | [0-9] | "_" )* ) + ::= ( "semanticId" | "semanticId." ) + + ::= ".externalSubjectId" | ".externalSubjectId." + ::= ".externalSubjectId" | ".externalSubjectId." + + ::= "specificAssetIds[" ( [0-9]* ) "]" ( ".name" | ".value" | ) + ::= "specificAssetIds[" ( [0-9]* ) "]" ( )? + + ::= ( "[" ( [0-9]* ) "]" )* ( "." )* + ::= ( [a-z] | [A-Z] ) ( ( [a-z] | [A-Z] | [0-9] | "_" | "-" )* ( [a-z] | [A-Z] | [0-9] | "_" ) )? ::= ( " " | "\t" | "\r" | "\n" )* 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 42875f76..64eb005e 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc @@ -22,7 +22,6 @@ The Asset Administration Shell propagates a Query Language inspired by the so-ca Note: The AAS Query Language and the AAS Access Rules xref:bibliography.adoc#bib3[[3\]] share the same BNF grammar. Therefore, the result is a superset, with `query` as the entrypoint for the Query Language. ==== - == Use Case Examples Examples for Use Cases are search queries in the submodels _DigitalNameplate_, _TechnicalData_ or _HandoverDocumentation_. @@ -507,6 +506,108 @@ 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" +$filter $sme.AddressInformation.Zipcode 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" +$filter $sme#value $sm#semanticId.keys[].value $eq "HIDE_VALUE" +$filter $sm#semanticId.keys[] $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 diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc b/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc index f5c81527..59d63b9b 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc @@ -3,7 +3,36 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Common JSON Schema for AAS Queries and Access Rules", "description": "This schema contains all classes that are shared between the AAS Query Language and the AAS Access Rule Language.", + "$ref": "#/definitions/Root", "definitions": { + "Root": { + "oneOf": [ + { + "type": "object", + "properties": { + "Query": { + "$ref": "#/definitions/Query" + } + }, + "required": [ + "Query" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "AllAccessPermissionRules": { + "$ref": "#/definitions/AllAccessPermissionRules" + } + }, + "required": [ + "AllAccessPermissionRules" + ], + "additionalProperties": false + } + ] + }, "standardString": { "type": "string", "pattern": "^(?!\\$).*" @@ -12,6 +41,10 @@ "type": "string", "pattern": "^((?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.(?:specificAssetIds(\\[[0-9]*\\])(?:\\.(?:name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(?:type|value))?)?)?)|submodels\\.(?:type|keys\\[\\d*\\](?:\\.(?:type|value))?))|submodels\\.(type|keys\\[\\d*\\](?:\\.(type|value))?)))|(?:\\$sm#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id))|(?:\\$sme(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?)*)?#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|value|valueType|language))|(?:\\$cd#(?:idShort|id))|(?:\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds(\\[[0-9]*\\])?(?:\\.(name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?)?)|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href)|submodelDescriptors(\\[[0-9]*\\])\\.(semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))|(?:\\$smdesc#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))$" }, + "fieldIdentifierFragment": { + "type": "string", + "pattern": "^(?:\\$aas#(?:idShort|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[\\d*\\](?:\\.externalSubjectId(?:\\.keys\\[\\d*\\])?)?|submodels|submodels\\.keys\\[\\d*\\])|(?:\\$sm#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|id))|(?:\\$sme(?:\\.(?:[a-zA-Z](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?(?:\\[\\d*\\])*)*)?(?:#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|value|valueType|language))?)|(?:\\$cd#idShort)|(?:\\$aasdesc#(?:idShort|assetKind|assetType|globalAssetId|description|displayName|extension|administration|specificAssetIds\\[\\d*\\](?:\\.externalSubjectId(?:\\.keys\\[\\d*\\])?)?|endpoints\\[\\d*\\]|submodelDescriptors\\[\\d*\\]|submodelDescriptors\\[\\d*\\]\\.(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|endpoints\\[\\d*\\])))|(?:\\$smdesc#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|description|displayName|extension|administration|supplementalSemanticId|endpoints\\[\\d*\\])))$" + }, "hexLiteralPattern": { "type": "string", "pattern": "^16#[0-9A-F]+$" @@ -650,45 +683,83 @@ "USEFORMULA": { "type": "string" }, - "FRAGMENT": { - "type": "string" - }, "FILTER": { - "$ref": "#/definitions/logicalExpression", + "$ref": "#/definitions/SecurityQueryFilter", "additionalProperties": false }, - "USEFILTER": { - "type": "string" + "FILTERLIST": { + "type": "array", + "items": { + "$ref": "#/definitions/SecurityQueryFilter" + } } }, - "oneOf": [ + "allOf": [ { - "required": [ - "ACL" + "oneOf": [ + { + "required": [ + "ACL" + ] + }, + { + "required": [ + "USEACL" + ] + } ] }, { - "required": [ - "USEACL" - ] - } - ], - "oneOf": [ - { - "required": [ - "OBJECTS" + "oneOf": [ + { + "required": [ + "OBJECTS" + ] + }, + { + "required": [ + "USEOBJECTS" + ] + } ] }, { - "required": [ - "USEOBJECTS" + "oneOf": [ + { + "required": [ + "FORMULA" + ] + }, + { + "required": [ + "USEFORMULA" + ] + } ] } ], + "additionalProperties": false + }, + "SecurityQueryFilter": { + "type": "object", + "properties": { + "FRAGMENT": { + "$ref": "#/definitions/fieldIdentifierFragment" + }, + "CONDITION": { + "$ref": "#/definitions/logicalExpression" + }, + "USEFORMULA": { + "type": "string" + } + }, + "required": [ + "FRAGMENT" + ], "oneOf": [ { "required": [ - "FORMULA" + "CONDITION" ] }, { @@ -698,10 +769,23 @@ } ], "additionalProperties": false - } - }, - "type": "object", - "properties": { + }, + "QueryFilter": { + "type": "object", + "properties": { + "$fragment": { + "$ref": "#/definitions/fieldIdentifierFragment" + }, + "$condition": { + "$ref": "#/definitions/logicalExpression" + } + }, + "required": [ + "$fragment", + "$condition" + ], + "additionalProperties": false + }, "Query": { "type": "object", "properties": { @@ -711,6 +795,12 @@ }, "$condition": { "$ref": "#/definitions/logicalExpression" + }, + "$filters": { + "type": "array", + "items": { + "$ref": "#/definitions/QueryFilter" + } } }, "required": [ @@ -832,19 +922,6 @@ ], "additionalProperties": false } - }, - "oneOf": [ - { - "required": [ - "Query" - ] - }, - { - "required": [ - "AllAccessPermissionRules" - ] - } - ], - "additionalProperties": false + } } -.... +.... \ No newline at end of file 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 434142ea..43770115 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf +++ b/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf @@ -1,6 +1,7 @@ ::= | - ::= ? + ::= ? ( "$filter" ( )* )? + ::= ::= "$select" "id" ::= | | | @@ -25,13 +26,13 @@ ::= ( ( "$starts-with" | "$ends-with" | "$contains" | "$regex") "(" "," ")" ) | ( ) | - ( ) | - ( ) + ( ) | + ( ) ::= ( ) | - ( ) | - ( ) + ( ) | + ( ) ::= @@ -51,7 +52,7 @@ ::= | | | | | ::= - | | | + | | | ::= | | @@ -85,7 +86,7 @@ ::= "time" "(" ( | ) ")" - + ::= ( "DEFATTRIBUTES" )* ( "DEFACLS" )* @@ -99,9 +100,18 @@ "OBJECTS:" ( )* ( )* - "FORMULA:" - ( | ) - ( "FILTER:" ( | ) )? + ( ( "FORMULA:" ) | ("USEFORMULA" ) ) + ( )? + ( )? + + ::= + "FILTER:" ( ) + + ::= + "FILTERLIST:" ( )* + + ::= + "FRAGMENT:" ( ( "CONDITION:" ) | ("USEFORMULA" ) ) ::= "ATTRIBUTES:" @@ -111,7 +121,7 @@ "ACCESS:" ::= - "USEACLS" + "USEACL" ::= "CREATE" | "READ" | "UPDATE" | "DELETE" | "EXECUTE" | "VIEW" | "ALL" @@ -163,9 +173,6 @@ ::= "USEOBJECTS" - ::= - "USEFORMULAS" - ::= ::= @@ -194,21 +201,62 @@ ::= ( "+" | "-" )? ( [0-9]+ ( "." [0-9]* )? | "." [0-9]+ ) ( ( "e" | "E" )? [0-9]+ ) ::= "16#" ( [0-9] | [A-F] )+ ::= "true" | "false" - ::= - ::= | | | | | - ::= "$aas#" ( "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels." ) - ::= "$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" | "endpoints" ( "[" ( [0-9]* ) "]" ) "." ) - ::= "interface" | "protocolinformation.href" - - ::= ( "type" | "keys" ( "[" ( [0-9]* ) "]" ) ( ".type" | ".value" ) ) - ::= ( "semanticId" | "semanticId." ) - ::= ( "specificAssetIds" ( "[" ( [0-9]* ) "]" ) ( ".name" | ".value" | ".externalSubjectId" | ".externalSubjectId." ) ) - ::= ( ("[" ( [0-9]* ) "]" )? ( "." )* ) - ::= ( ( [a-z] | [A-Z] ) ( [a-z] | [A-Z] | [0-9] | "_" )* ) - ::= ( " " | "\t" | "\r" | "\n" )+ \ No newline at end of file + ::= "$aas#" + ::= "$sm#" + ::= "$sme" ( "." )? ("#" )? + ::= "$cd#" + ::= "$aasdesc#" + ::= "$smdesc#" + + ::= "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels." + ::= | "idShort" | "id" + ::= | "idShort" | "value" | "valueType" | "language" + ::= "idShort" | "id" + + ::= "idShort" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels" | "submodels." + ::= | "idShort" | "id" + ::= | "idShort" | "value" | "valueType" | "language" + ::= "idShort" + + ::= "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | | | "." + ::= "idShort" | "description" | "displayName" | "extension" | "administration" | "assetKind" | "assetType" | "globalAssetId" | | | | "." + + ::= "submodelDescriptors[" ( [0-9]* ) "]" + ::= | "idShort" | "id" | + ::= | "idShort" | "description" | "displayName" | "extension" | "administration" | "supplementalSemanticId" | + + ::= + ::= "endpoints[" ( [0-9]* ) "]" + ::= ".interface" | ".protocolinformation.href" + ::= + + ::= "semanticId" | "semanticId." + ::= ".externalSubjectId" | ".externalSubjectId." + ::= ( "type" | "keys[" ( [0-9]* ) "]" ( ".type" | ".value" ) ) + + ::= "semanticId" | "semanticId." + ::= ".externalSubjectId" | ".externalSubjectId." + ::= ( "keys[" ( [0-9]* ) "]") + + ::= + ::= "specificAssetIds[" ( [0-9]* ) "]" + ::= ".name" | ".value" | + + ::= ? + ::= + + ::= ("[" ( [0-9]* ) "]")* ("." )* + ::= ( [a-z] | [A-Z] ) ( ( [a-z] | [A-Z] | [0-9] | "_" | "-" )* ( [a-z] | [A-Z] | [0-9] | "_" ) )? + + ::= ( " " | "\t" | "\r" | "\n" )* \ No newline at end of file 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 34f20750..9d2ab1db 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 @@ -12,6 +12,10 @@ "type": "string", "pattern": "^((?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.(?:specificAssetIds(\\[[0-9]*\\])(?:\\.(?:name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(?:type|value))?)?)?)|submodels\\.(?:type|keys\\[\\d*\\](?:\\.(?:type|value))?))|submodels\\.(type|keys\\[\\d*\\](?:\\.(type|value))?)))|(?:\\$sm#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id))|(?:\\$sme(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?(?:\\.[a-zA-Z][a-zA-Z0-9_]*(\\[[0-9]*\\])?)*)?#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|value|valueType|language))|(?:\\$cd#(?:idShort|id))|(?:\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds(\\[[0-9]*\\])?(?:\\.(name|value|externalSubjectId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?)?)|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href)|submodelDescriptors(\\[[0-9]*\\])\\.(semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))|(?:\\$smdesc#(?:semanticId(?:\\.type|\\.keys\\[\\d*\\](?:\\.(type|value))?)?|idShort|id|endpoints(\\[[0-9]*\\])\\.(interface|protocolinformation\\.href))))$" }, + "fieldIdentifierFragment": { + "type": "string", + "pattern": "^(?:\\$aas#(?:idShort|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[\\d*\\](?:\\.externalSubjectId(?:\\.keys\\[\\d*\\])?)?|submodels|submodels\\.keys\\[\\d*\\])|(?:\\$sm#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|id))|(?:\\$sme(?:\\.(?:[a-zA-Z](?:[a-zA-Z0-9_-]*[a-zA-Z0-9_])?(?:\\[\\d*\\])*)*)?(?:#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|value|valueType|language))?)|(?:\\$cd#idShort)|(?:\\$aasdesc#(?:idShort|assetKind|assetType|globalAssetId|description|displayName|extension|administration|specificAssetIds\\[\\d*\\](?:\\.externalSubjectId(?:\\.keys\\[\\d*\\])?)?|endpoints\\[\\d*\\]|submodelDescriptors\\[\\d*\\]|submodelDescriptors\\[\\d*\\]\\.(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|endpoints\\[\\d*\\])))|(?:\\$smdesc#(?:semanticId(?:\\.keys\\[\\d*\\])?|idShort|description|displayName|extension|administration|supplementalSemanticId|endpoints\\[\\d*\\])))$" + }, "hexLiteralPattern": { "type": "string", "pattern": "^16#[0-9A-F]+$" @@ -464,222 +468,19 @@ ], "additionalProperties": false }, - "attributeItem": { - "oneOf": [ - { - "required": [ - "CLAIM" - ] - }, - { - "required": [ - "GLOBAL" - ] - }, - { - "required": [ - "REFERENCE" - ] - } - ], - "properties": { - "CLAIM": { - "type": "string" - }, - "GLOBAL": { - "type": "string", - "enum": [ - "LOCALNOW", - "UTCNOW", - "CLIENTNOW", - "ANONYMOUS" - ] - }, - "REFERENCE": { - "type": "string" - } - }, - "additionalProperties": false - }, - "objectItem": { - "oneOf": [ - { - "required": [ - "ROUTE" - ] - }, - { - "required": [ - "IDENTIFIABLE" - ] - }, - { - "required": [ - "REFERABLE" - ] - }, - { - "required": [ - "FRAGMENT" - ] - }, - { - "required": [ - "DESCRIPTOR" - ] - } - ], - "properties": { - "ROUTE": { - "type": "string" - }, - "IDENTIFIABLE": { - "type": "string" - }, - "REFERABLE": { - "type": "string" - }, - "FRAGMENT": { - "type": "string" - }, - "DESCRIPTOR": { - "type": "string" - } - }, - "additionalProperties": false - }, - "rightsEnum": { - "type": "string", - "enum": [ - "CREATE", - "READ", - "UPDATE", - "DELETE", - "EXECUTE", - "VIEW", - "ALL" - ], - "additionalProperties": false - }, - "ACL": { + "QueryFilter": { "type": "object", "properties": { - "ATTRIBUTES": { - "type": "array", - "items": { - "$ref": "#/definitions/attributeItem" - } - }, - "USEATTRIBUTES": { - "type": "string" - }, - "RIGHTS": { - "type": "array", - "items": { - "$ref": "#/definitions/rightsEnum" - } + "$fragment": { + "$ref": "#/definitions/fieldIdentifierFragment" }, - "ACCESS": { - "type": "string", - "enum": [ - "ALLOW", - "DISABLED" - ] + "$condition": { + "$ref": "#/definitions/logicalExpression" } }, "required": [ - "RIGHTS", - "ACCESS" - ], - "oneOf": [ - { - "required": [ - "ATTRIBUTES" - ] - }, - { - "required": [ - "USEATTRIBUTES" - ] - } - ], - "additionalProperties": false - }, - "AccessPermissionRule": { - "type": "object", - "properties": { - "ACL": { - "$ref": "#/definitions/ACL" - }, - "USEACL": { - "type": "string" - }, - "OBJECTS": { - "type": "array", - "items": { - "$ref": "#/definitions/objectItem" - }, - "additionalProperties": false - }, - "USEOBJECTS": { - "type": "array", - "items": { - "type": "string" - } - }, - "FORMULA": { - "$ref": "#/definitions/logicalExpression", - "additionalProperties": false - }, - "USEFORMULA": { - "type": "string" - }, - "FRAGMENT": { - "type": "string" - }, - "FILTER": { - "$ref": "#/definitions/logicalExpression", - "additionalProperties": false - }, - "USEFILTER": { - "type": "string" - } - }, - "oneOf": [ - { - "required": [ - "ACL" - ] - }, - { - "required": [ - "USEACL" - ] - } - ], - "oneOf": [ - { - "required": [ - "OBJECTS" - ] - }, - { - "required": [ - "USEOBJECTS" - ] - } - ], - "oneOf": [ - { - "required": [ - "FORMULA" - ] - }, - { - "required": [ - "USEFORMULA" - ] - } + "$fragment", + "$condition" ], "additionalProperties": false }, @@ -692,124 +493,16 @@ }, "$condition": { "$ref": "#/definitions/logicalExpression" - } - }, - "required": [ - "$condition" - ], - "additionalProperties": false - }, - "AllAccessPermissionRules": { - "type": "object", - "properties": { - "DEFATTRIBUTES": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "attributes": { - "type": "array", - "items": { - "$ref": "#/definitions/attributeItem" - } - } - }, - "required": [ - "name", - "attributes" - ], - "additionalProperties": false - } - }, - "DEFACLS": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "acl": { - "$ref": "#/definitions/ACL" - } - }, - "required": [ - "name", - "acl" - ], - "additionalProperties": false - } }, - "DEFOBJECTS": { + "$filters": { "type": "array", "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "objects": { - "type": "array", - "items": { - "$ref": "#/definitions/objectItem" - } - }, - "USEOBJECTS": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "name" - ], - "oneOf": [ - { - "required": [ - "objects" - ] - }, - { - "required": [ - "USEOBJECTS" - ] - } - ], - "additionalProperties": false - } - }, - "DEFFORMULAS": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "formula": { - "$ref": "#/definitions/logicalExpression" - } - }, - "required": [ - "name", - "formula" - ], - "additionalProperties": false - } - }, - "rules": { - "type": "array", - "items": { - "$ref": "#/definitions/AccessPermissionRule" + "$ref": "#/definitions/QueryFilter" } } }, "required": [ - "rules" + "$condition" ], "additionalProperties": false }