diff --git a/CHANGELOG.md b/CHANGELOG.md index 8263c7b2..176419ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.6.0-RC1 +## 0.6.0-RC2 ### Added - +- Update API to AAS to v3.0.2_SSP-001 (Breaking changes) + - Changed type of aasIdentifier and submodelIdentifier from `byte[]` to `String` + - Changed patterns to `^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$` ## fixed - Update Spring Boot to version 3.3.4 - Update logback to version 1.5.8 diff --git a/backend/src/main/java/org/eclipse/tractusx/semantics/registry/controller/AssetAdministrationShellApiDelegate.java b/backend/src/main/java/org/eclipse/tractusx/semantics/registry/controller/AssetAdministrationShellApiDelegate.java index 21a7f184..0b3dd438 100644 --- a/backend/src/main/java/org/eclipse/tractusx/semantics/registry/controller/AssetAdministrationShellApiDelegate.java +++ b/backend/src/main/java/org/eclipse/tractusx/semantics/registry/controller/AssetAdministrationShellApiDelegate.java @@ -32,9 +32,9 @@ import org.eclipse.tractusx.semantics.aas.registry.model.AssetAdministrationShellDescriptor; import org.eclipse.tractusx.semantics.aas.registry.model.AssetKind; import org.eclipse.tractusx.semantics.aas.registry.model.AssetLink; -import org.eclipse.tractusx.semantics.aas.registry.model.GetAllAssetAdministrationShellIdsByAssetLink200Response; import org.eclipse.tractusx.semantics.aas.registry.model.GetAssetAdministrationShellDescriptorsResult; import org.eclipse.tractusx.semantics.aas.registry.model.GetSubmodelDescriptorsResult; +import org.eclipse.tractusx.semantics.aas.registry.model.InlineResponse200; import org.eclipse.tractusx.semantics.aas.registry.model.SearchAllShellsByAssetLink200Response; import org.eclipse.tractusx.semantics.aas.registry.model.ServiceDescription; import org.eclipse.tractusx.semantics.aas.registry.model.SpecificAssetId; @@ -84,18 +84,17 @@ public ResponseEntity getDescription() { } @Override - public ResponseEntity deleteAssetAdministrationShellDescriptorById( byte[] aasIdentifier ) { + public ResponseEntity deleteAssetAdministrationShellDescriptorById( String aasIdentifier ) { shellService.deleteShell( getDecodedId(aasIdentifier) ); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @Override - public ResponseEntity deleteAllAssetLinksById(byte[] aasIdentifier) { - + public ResponseEntity deleteAllAssetLinksById(String aasIdentifier) { shellService.deleteAllIdentifiers(getDecodedId(aasIdentifier)); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @Override - public ResponseEntity deleteSubmodelDescriptorByIdThroughSuperpath( byte[] aasIdentifier, byte[] submodelIdentifier, @RequestHeader String externalSubjectId ) { + public ResponseEntity deleteSubmodelDescriptorByIdThroughSuperpath( String aasIdentifier, String submodelIdentifier, @RequestHeader String externalSubjectId ) { shellService.deleteSubmodel(getDecodedId( aasIdentifier ), getDecodedId( submodelIdentifier ),getExternalSubjectIdOrEmpty( externalSubjectId )); return new ResponseEntity<>(HttpStatus.NO_CONTENT); @@ -110,7 +109,7 @@ public ResponseEntity getAllAssetA } @Override - public ResponseEntity getAllSubmodelDescriptorsThroughSuperpath( byte[] aasIdentifier, Integer limit, String cursor, @RequestHeader String externalSubjectId ) { + public ResponseEntity getAllSubmodelDescriptorsThroughSuperpath( String aasIdentifier, Integer limit, String cursor, @RequestHeader String externalSubjectId ) { Shell savedShell = shellService.findShellByExternalIdAndExternalSubjectId(getDecodedId( aasIdentifier ),getExternalSubjectIdOrEmpty(externalSubjectId)); SubmodelCollectionDto dto = shellService.findAllSubmodel( limit,cursor, savedShell); GetSubmodelDescriptorsResult result= submodelMapper.toApiDto( dto ); @@ -118,14 +117,14 @@ public ResponseEntity getAllSubmodelDescriptorsThr } @Override - public ResponseEntity getAssetAdministrationShellDescriptorById( byte[] aasIdentifier, @RequestHeader String externalSubjectId ) { + public ResponseEntity getAssetAdministrationShellDescriptorById( String aasIdentifier, @RequestHeader String externalSubjectId ) { String decodedAasIdentifier = getDecodedId( aasIdentifier ); Shell saved = shellService.findShellByExternalIdAndExternalSubjectId(decodedAasIdentifier, getExternalSubjectIdOrEmpty(externalSubjectId)); return new ResponseEntity<>(shellMapper.toApiDto(saved), HttpStatus.OK); } @Override - public ResponseEntity getSubmodelDescriptorByIdThroughSuperpath( byte[] aasIdentifier, byte[] submodelIdentifier, @RequestHeader String externalSubjectId ) { + public ResponseEntity getSubmodelDescriptorByIdThroughSuperpath( String aasIdentifier, String submodelIdentifier, @RequestHeader String externalSubjectId ) { Submodel submodel = shellService.findSubmodelByExternalId(getDecodedId( aasIdentifier ), getDecodedId( submodelIdentifier ),getExternalSubjectIdOrEmpty( externalSubjectId )); return new ResponseEntity<>(submodelMapper.toApiDto(submodel), HttpStatus.OK); } @@ -140,7 +139,7 @@ public ResponseEntity postAssetAdministratio } @Override - public ResponseEntity postSubmodelDescriptorThroughSuperpath( byte[] aasIdentifier, @RequestHeader String externalSubjectId, SubmodelDescriptor submodelDescriptor ) { + public ResponseEntity postSubmodelDescriptorThroughSuperpath( String aasIdentifier, SubmodelDescriptor submodelDescriptor, @RequestHeader String externalSubjectId ) { Submodel toBeSaved = submodelMapper.fromApiDto(submodelDescriptor); toBeSaved.setIdExternal( submodelDescriptor.getId() ); shellService.mapSubmodel( Set.of(toBeSaved) ); @@ -149,7 +148,7 @@ public ResponseEntity postSubmodelDescriptorThroughSuperpath } @Override - public ResponseEntity putAssetAdministrationShellDescriptorById( byte[] aasIdentifier, AssetAdministrationShellDescriptor assetAdministrationShellDescriptor, @RequestHeader String externalSubjectId ) { + public ResponseEntity putAssetAdministrationShellDescriptorById( String aasIdentifier, AssetAdministrationShellDescriptor assetAdministrationShellDescriptor, @RequestHeader String externalSubjectId ) { Shell shell = shellMapper.fromApiDto( assetAdministrationShellDescriptor ); Shell shellFromDb = shellService.findShellByExternalIdWithoutFiltering( getDecodedId( aasIdentifier ) ); shellService.update( shell.withId( shellFromDb.getId() ).withIdExternal( getDecodedId( aasIdentifier ) ), getDecodedId( aasIdentifier ) ); @@ -157,18 +156,18 @@ public ResponseEntity putAssetAdministrationShellDescriptorById( byte[] aa } @Override - public ResponseEntity putSubmodelDescriptorByIdThroughSuperpath( byte[] aasIdentifier, byte[] submodelIdentifier, @RequestHeader String externalSubjectId, SubmodelDescriptor submodelDescriptor ) { + public ResponseEntity putSubmodelDescriptorByIdThroughSuperpath( String aasIdentifier, String submodelIdentifier, SubmodelDescriptor submodelDescriptor, @RequestHeader String externalSubjectId ) { shellService.deleteSubmodel(getDecodedId( aasIdentifier ), getDecodedId( submodelIdentifier ),getExternalSubjectIdOrEmpty( externalSubjectId )); submodelDescriptor.setId( getDecodedId( submodelIdentifier )); - postSubmodelDescriptorThroughSuperpath(aasIdentifier,externalSubjectId,submodelDescriptor); + postSubmodelDescriptorThroughSuperpath(aasIdentifier,submodelDescriptor,externalSubjectId ); return new ResponseEntity<>( HttpStatus.NO_CONTENT ); } @Override - public ResponseEntity getAllAssetAdministrationShellIdsByAssetLink(List assetIds, + public ResponseEntity getAllAssetAdministrationShellIdsByAssetLink(List assetIds, Integer limit, String cursor, @RequestHeader String externalSubjectId) { if (assetIds == null || assetIds.isEmpty()) { - return new ResponseEntity<>(new GetAllAssetAdministrationShellIdsByAssetLink200Response(), HttpStatus.OK); + return new ResponseEntity<>(new InlineResponse200(), HttpStatus.OK); } List listSpecificAssetId = assetIds.stream().map( this::decodeSAID).collect( Collectors.toList()); @@ -190,25 +189,25 @@ public ResponseEntity searchAllShellsByAs return new ResponseEntity<>( result, HttpStatus.OK ); } - private SpecificAssetId decodeSAID(byte[] encodedId){ + private SpecificAssetId decodeSAID(String encodedId){ ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion( JsonInclude.Include.NON_NULL); try { - byte[] decodedBytes = Base64.getUrlDecoder().decode( encodedId ); - return mapper.readValue(decodedBytes, SpecificAssetId.class ); + String decodeString = new String(Base64.getUrlDecoder().decode( encodedId )); + return mapper.readValue(decodeString, SpecificAssetId.class ); } catch (Exception e ) { throw new IllegalArgumentException("Incorrect Base64 encoded value provided as parameter"); } } @Override - public ResponseEntity> getAllAssetLinksById(byte[] aasIdentifier,@RequestHeader String externalSubjectId) { + public ResponseEntity> getAllAssetLinksById(String aasIdentifier,@RequestHeader String externalSubjectId) { Set identifiers = shellService.findShellIdentifiersByExternalShellId(getDecodedId( aasIdentifier ),getExternalSubjectIdOrEmpty(externalSubjectId)); return new ResponseEntity<>(shellMapper.toApiDto(identifiers), HttpStatus.OK); } @Override - public ResponseEntity> postAllAssetLinksById(byte[] aasIdentifier, List specificAssetId, @RequestHeader String externalSubjectId ) { + public ResponseEntity> postAllAssetLinksById(String aasIdentifier, List specificAssetId, @RequestHeader String externalSubjectId ) { Set shellIdentifiers = shellService.save(getDecodedId( aasIdentifier ), shellMapper.fromApiDto(specificAssetId),getExternalSubjectIdOrEmpty( externalSubjectId )); List list = shellMapper.toApiDto(shellIdentifiers); return new ResponseEntity<>(list, HttpStatus.CREATED); @@ -218,7 +217,7 @@ private String getExternalSubjectIdOrEmpty(String externalSubjectId) { return (null ==externalSubjectId) ? "" : externalSubjectId; } - private String getDecodedId( byte[] aasIdentifier ) { + private String getDecodedId( String aasIdentifier ) { try { byte[] decodedBytes = Base64.getUrlDecoder().decode( aasIdentifier ); return new String( decodedBytes ); diff --git a/backend/src/main/java/org/eclipse/tractusx/semantics/registry/service/ShellService.java b/backend/src/main/java/org/eclipse/tractusx/semantics/registry/service/ShellService.java index 0b8c518e..248c1e2e 100644 --- a/backend/src/main/java/org/eclipse/tractusx/semantics/registry/service/ShellService.java +++ b/backend/src/main/java/org/eclipse/tractusx/semantics/registry/service/ShellService.java @@ -40,7 +40,7 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.semantics.RegistryProperties; -import org.eclipse.tractusx.semantics.aas.registry.model.GetAllAssetAdministrationShellIdsByAssetLink200Response; +import org.eclipse.tractusx.semantics.aas.registry.model.InlineResponse200; import org.eclipse.tractusx.semantics.aas.registry.model.PagedResultPagingMetadata; import org.eclipse.tractusx.semantics.aas.registry.model.SearchAllShellsByAssetLink200Response; import org.eclipse.tractusx.semantics.accesscontrol.api.exception.DenyAccessException; @@ -271,7 +271,7 @@ private Specification hasShellFkId( Shell shellId ) { } @Transactional( readOnly = true ) - public GetAllAssetAdministrationShellIdsByAssetLink200Response findExternalShellIdsByIdentifiersByExactMatch( Set shellIdentifiers, + public InlineResponse200 findExternalShellIdsByIdentifiersByExactMatch( Set shellIdentifiers, Integer pageSize, String cursor, String externalSubjectId ) { pageSize = getPageSize( pageSize ); @@ -286,12 +286,12 @@ public GetAllAssetAdministrationShellIdsByAssetLink200Response findExternalShell final var assetIdList = visibleAssetIds.stream().limit( pageSize ).toList(); final String nextCursor = getCursorEncoded( visibleAssetIds, assetIdList ); - final var response = new GetAllAssetAdministrationShellIdsByAssetLink200Response(); + final var response = new InlineResponse200(); response.setResult( assetIdList ); response.setPagingMetadata( new PagedResultPagingMetadata().cursor( nextCursor ) ); return response; } catch ( DenyAccessException e ) { - final var response = new GetAllAssetAdministrationShellIdsByAssetLink200Response(); + final var response = new InlineResponse200(); response.setResult( Collections.emptyList() ); return response; } diff --git a/backend/src/main/resources/static/aas-registry-openapi.yaml b/backend/src/main/resources/static/aas-registry-openapi.yaml index 4536f33b..79696249 100644 --- a/backend/src/main/resources/static/aas-registry-openapi.yaml +++ b/backend/src/main/resources/static/aas-registry-openapi.yaml @@ -23,18 +23,18 @@ openapi: 3.0.3 info: title: DotAAS Part 2 | HTTP/REST | Asset Administration Shell Registry Service Specification - description: "The Full Profile of the Asset Administration Shell Registry Service Specification as part of the Specification of the Asset Administration Shell: Part 2. Publisher: Industrial Digital Twin Association (IDTA) April 2023" + description: "The Full Profile of the Asset Administration Shell Registry Service Specification as part of the [Specification of the Asset Administration Shell: Part 2](http://industrialdigitaltwin.org/en/content-hub). \nPublisher: Industrial Digital Twin Association (IDTA) 2023" contact: name: Industrial Digital Twin Association (IDTA) email: info@idtwin.org license: name: CC BY 4.0 url: https://creativecommons.org/licenses/by/4.0/ - version: V3.0_SSP-001 + version: V3.0.2_SSP-001 security: - bearerAuth: [] servers: - - url: "{protocol}://{host_name}:{port}{context_root}/api/{version_prefix}/" + - url: "{protocol}://{host_name}:{port}/api/{version_prefix}" variables: protocol: description: Allows access through http and https (recommended) @@ -51,14 +51,10 @@ servers: enum: - "80" - "443" - - "4243" version_prefix: default: v3 enum: - v3 - context_root: - description: Context root for the API - default: "" paths: /shell-descriptors: get: @@ -93,7 +89,7 @@ paths: schema: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string - $ref: '#/components/parameters/ExternalSubjectIdHeader' responses: @@ -142,10 +138,17 @@ paths: application/json: schema: $ref: '#/components/schemas/AssetAdministrationShellDescriptor' - required: false + required: true responses: "201": description: Asset Administration Shell Descriptor created successfully + headers: + Location: + description: URL of the newly created resource + style: simple + explode: false + schema: + type: string content: application/json: schema: @@ -197,7 +200,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' responses: "200": @@ -252,7 +254,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' requestBody: description: Asset Administration Shell Descriptor object @@ -310,7 +311,6 @@ paths: explode: false schema: type: string - format: byte responses: "204": description: Asset Administration Shell Descriptor deleted successfully @@ -355,16 +355,17 @@ paths: explode: false schema: type: string - format: byte - name: limit in: query description: The maximum number of elements in the response array + required: false schema: minimum: 1 type: integer - name: cursor in: query description: A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue + required: false schema: type: string - $ref: '#/components/parameters/ExternalSubjectIdHeader' @@ -421,7 +422,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' requestBody: description: Submodel Descriptor object @@ -429,9 +429,17 @@ paths: application/json: schema: $ref: '#/components/schemas/SubmodelDescriptor' + required: true responses: "201": description: Submodel Descriptor created successfully + headers: + Location: + description: URL of the newly created resource + style: simple + explode: false + schema: + type: string content: application/json: schema: @@ -489,7 +497,6 @@ paths: explode: false schema: type: string - format: byte - name: submodelIdentifier in: path description: The Submodel’s unique id (UTF8-BASE64-URL-encoded) @@ -498,7 +505,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' responses: "200": @@ -553,7 +559,6 @@ paths: explode: false schema: type: string - format: byte - name: submodelIdentifier in: path description: The Submodel’s unique id (UTF8-BASE64-URL-encoded) @@ -562,7 +567,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' requestBody: description: Submodel Descriptor object @@ -570,6 +574,7 @@ paths: application/json: schema: $ref: '#/components/schemas/SubmodelDescriptor' + required: true responses: "204": description: Submodel Descriptor updated successfully @@ -619,7 +624,6 @@ paths: explode: false schema: type: string - format: byte - name: submodelIdentifier in: path description: The Submodel’s unique id (UTF8-BASE64-URL-encoded) @@ -628,7 +632,6 @@ paths: explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' responses: "204": @@ -689,34 +692,28 @@ paths: /lookup/shells: get: tags: - - Registry and Discovery Interface - summary: Returns a list of Asset Administration Shell ids based on Asset identifier key-value-pairs. Only the Shell ids are returned when all provided key-value pairs match. - operationId: getAllAssetAdministrationShellIdsByAssetLink + - Asset Administration Shell Basic Discovery API + summary: Returns a list of Asset Administration Shell ids linked to specific Asset identifiers + operationId: GetAllAssetAdministrationShellIdsByAssetLink parameters: - name: assetIds in: query - description: The key-value-pair of an Asset identifier + description: "A list of specific Asset identifiers. Every single value asset identifier is a base64-url-encoded [SpecificAssetId](https://api.swaggerhub.com/domains/Plattform_i40/Part1-MetaModel-Schemas/V3.0.2#/components/schemas/SpecificAssetId)." required: false style: form explode: true - # The form style defined in the AAS API does not match with the provided example. - # the "content" is the correct way to accept json encoded query parameters - # style: form - # explode: true schema: type: array - maxItems: 10000 + example: ?assetIds=eyAibmFtZSI6ICJzb21lLWFzc2V0LWlkIiwgInZhbHVlIjogImh0dHA6Ly9leGFtcGxlLWNvbXBhbnkuY29tL215QXNzZXQiLCAiZXh0ZXJuYWxTdWJqZWN0SWQiOiB7ICJrZXlzIjogWyB7ICJ0eXBlIjogIkdsb2JhbFJlZmVyZW5jZSIsICJ2YWx1ZSI6ICJodHRwOi8vZXhhbXBsZS1jb21wYW55LmNvbS9leGFtcGxlLWNvbXBhbnlzLWFzc2V0LWtleXMiIH0gXSwgInR5cGUiOiAiRXh0ZXJuYWxSZWZlcmVuY2UiIH0gfQ&assetIds=eyAibmFtZSI6ICJzb21lLW90aGVyLWFzc2V0LWlkIiwgInZhbHVlIjogIjEyMzQ1QUJDIiwgImV4dGVybmFsU3ViamVjdElkIjogeyAia2V5cyI6IFsgeyAidHlwZSI6ICJHbG9iYWxSZWZlcmVuY2UiLCAidmFsdWUiOiAiaHR0cDovL215LW93bi1jb21wYW55LmNvbS9rZXlzIiB9IF0sICJ0eXBlIjogIkV4dGVybmFsUmVmZXJlbmNlIiB9IH0 items: type: string - format: byte - example: '?assetIds=eyAibmFtZSI6ICJzb21lLWFzc2V0LWlkIiwgInZhbHVlIjogImh0dHA6Ly9leGFtcGxlLWNvbXBhbnkuY29tL215QXNzZXQiLCAiZXh0ZXJuYWxTdWJqZWN0SWQiOiB7ICJrZXlzIjogWyB7ICJ0eXBlIjogIkdsb2JhbFJlZmVyZW5jZSIsICJ2YWx1ZSI6ICJodHRwOi8vZXhhbXBsZS1jb21wYW55LmNvbS9leGFtcGxlLWNvbXBhbnlzLWFzc2V0LWtleXMiIH0gXSwgInR5cGUiOiAiR2xvYmFsUmVmZXJlbmNlIiB9IH0&assetIds=eyAibmFtZSI6ICJzb21lLW90aGVyLWFzc2V0LWlkIiwgInZhbHVlIjogIjEyMzQ1QUJDIiwgImV4dGVybmFsU3ViamVjdElkIjogeyAia2V5cyI6IFsgeyAidHlwZSI6ICJHbG9iYWxSZWZlcmVuY2UiLCAidmFsdWUiOiAiaHR0cDovL215LW93bi1jb21wYW55LmNvbS9rZXlzIiB9IF0sICJ0eXBlIjogIkdsb2JhbFJlZmVyZW5jZSIgfSB9' - name: limit in: query description: The maximum number of elements in the response array required: false schema: - type: integer minimum: 1 + type: integer - name: cursor in: query description: A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue @@ -730,20 +727,16 @@ paths: content: application/json: schema: - allOf: - - $ref: '#/components/schemas/PagedResult' - - type: object - properties: - result: - type: array - maxItems: 10000 - items: - type: string - examples: - complete: - $ref: '#/components/examples/lookup-shells-by-aas-identifier-response' + $ref: '#/components/schemas/inline_response_200' + + default: + description: Default error handling for unmentioned status codes + content: + application/json: + schema: + $ref: '#/components/schemas/Result' x-semanticIds: - - https://admin-shell.io/aas/API/GetAllAssetAdministrationShellIdsByAssetLink/1/0/RC02 + - https://admin-shell.io/aas/API/GetAllAssetAdministrationShellIdsByAssetLink/3/0 /lookup/shellsByAssetLink: post: tags: @@ -801,99 +794,132 @@ paths: /lookup/shells/{aasIdentifier}: get: tags: - - Registry and Discovery Interface - summary: Returns a list of Asset identifier key-value-pairs based on an Asset Administration Shell id to edit discoverable content + - Asset Administration Shell Basic Discovery API + summary: Returns a list of specific Asset identifiers based on an Asset Administration Shell id to edit discoverable content operationId: GetAllAssetLinksById parameters: - name: aasIdentifier in: path - description: The Asset Administration Shell’s unique id (BASE64-URL-encoded) + description: The Asset Administration Shell’s unique id (UTF8-BASE64-URL-encoded) required: true style: simple explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' responses: "200": - description: Requested Asset identifier key-value-pairs + description: Requested specific Asset identifiers content: application/json: schema: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SpecificAssetId' - examples: - complete: - $ref: '#/components/examples/lookup-specific-asset-ids' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Result' + default: + description: Default error handling for unmentioned status codes + content: + application/json: + schema: + $ref: '#/components/schemas/Result' x-semanticIds: - - https://admin-shell.io/aas/API/GetAllAssetLinksById/1/0/RC02 + - https://admin-shell.io/aas/API/GetAllAssetLinksById/3/0 post: tags: - - Registry and Discovery Interface - summary: Creates all Asset identifier key-value-pair linked to an Asset Administration Shell to edit discoverable content + - Asset Administration Shell Basic Discovery API + summary: Creates specific Asset identifiers linked to an Asset Administration Shell to edit discoverable content operationId: PostAllAssetLinksById parameters: - name: aasIdentifier in: path - description: The Asset Administration Shell’s unique id (BASE64-URL-encoded) + description: The Asset Administration Shell’s unique id (UTF8-BASE64-URL-encoded) required: true style: simple explode: false schema: type: string - format: byte - $ref: '#/components/parameters/ExternalSubjectIdHeader' requestBody: - description: Asset identifier key-value-pairs + description: A list of specific Asset identifiers content: application/json: schema: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SpecificAssetId' - examples: - complete: - $ref: '#/components/examples/lookup-specific-asset-ids' required: true responses: "201": - description: Asset identifier key-value-pairs created successfully + description: Specific Asset identifiers created successfully content: application/json: schema: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SpecificAssetId' - examples: - complete: - $ref: '#/components/examples/lookup-specific-asset-ids' + "400": + description: "Bad Request, e.g. the request parameters of the format of the request body is wrong." + content: + application/json: + schema: + $ref: '#/components/schemas/Result' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Result' + "409": + description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request." + content: + application/json: + schema: + $ref: '#/components/schemas/Result' + default: + description: Default error handling for unmentioned status codes + content: + application/json: + schema: + $ref: '#/components/schemas/Result' x-semanticIds: - - https://admin-shell.io/aas/API/PostAllAssetLinksById/1/0/RC02 + - https://admin-shell.io/aas/API/PostAllAssetLinksById/3/0 delete: tags: - - Registry and Discovery Interface - summary: Deletes all Asset identifier key-value-pair linked to an Asset Administration Shell to edit discoverable content + - Asset Administration Shell Basic Discovery API + summary: Deletes all specific Asset identifiers linked to an Asset Administration Shell to edit discoverable content operationId: DeleteAllAssetLinksById parameters: - name: aasIdentifier in: path - description: The Asset Administration Shell’s unique id (BASE64-URL-encoded) + description: The Asset Administration Shell’s unique id (UTF8-BASE64-URL-encoded) required: true style: simple explode: false schema: type: string - format: byte responses: "204": - description: Asset identifier key-value-pairs deleted successfully + description: Specific Asset identifiers deleted successfully + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Result' + default: + description: Default error handling for unmentioned status codes + content: + application/json: + schema: + $ref: '#/components/schemas/Result' x-semanticIds: - - https://admin-shell.io/aas/API/DeleteAllAssetLinksById/1/0/RC02 + - https://admin-shell.io/aas/API/DeleteAllAssetLinksById/3/0 /submodel-descriptor/authorized: post: tags: @@ -992,14 +1018,12 @@ components: - NotApplicable - Type GetAssetAdministrationShellDescriptorsResult: - type: object allOf: - $ref: '#/components/schemas/PagedResult' - type: object properties: result: type: array - maxItems: 10000 items: $ref: '#/components/schemas/AssetAdministrationShellDescriptor' PagedResult: @@ -1011,7 +1035,7 @@ components: required: - id type: object - example: {"description":[{"language":"de","text":"hello text"},{"language":"en","text":"hello s"}],"displayName":[{"language":"de","text":"this is an example description1"}],"endpoints":[{"interface":"interfaceNameExample","protocolInformation":{"href":"endpointAddressExample","endpointProtocol":"endpointProtocolExample","endpointProtocolVersion":["e"],"subprotocol":"subprotocolExample","subprotocolBody":"subprotocolBodyExample","subprotocolBodyEncoding":"subprotocolBodyExample","securityAttributes":[{"type":"NONE","key": "Security Attribute key","value": "Security Attribute value"}]}}],"idShort":"idShortExample","id":"e1eba3d7-91f0-4dac-a730-eaa1d35e035c","specificAssetIds":[{"supplementalSemanticIds":[{"type":"ExternalReference","keys":[{"type":"Submodel","value":"semanticIdExample"}]}],"name":"identifier1KeyExample","value":"identifier1ValueExample"},{"supplementalSemanticIds":[{"type":"ExternalReference","keys":[{"type":"Submodel","value":"semanticIdExample"}]}],"name":"identifier2KeyExample","value":"identifier2ValueExample"}],"submodelDescriptors":[{"endpoints":[{"interface":"interfaceNameExample","protocolInformation":{"href":"endpointAddressExample","endpointProtocol":"endpointProtocolExample","endpointProtocolVersion":["e"],"subprotocol":"subprotocolExample","subprotocolBody":"subprotocolBodyExample","subprotocolBodyEncoding":"subprotocolBodyExample","securityAttributes":[{"type":"NONE","key": "Security Attribute key","value": "Security Attribute value"}]}}],"idShort":"idShortExample","id":"cd47615b-daf3-4036-8670-d2f89349d388","semanticId":{"type":"ExternalReference","keys":[{"type":"Submodel","value":"semanticIdExample"}]},"description":[{"language":"de","text":"hello text"},{"language":"en","text":"hello s"}]}]} + example: {"id":"https://example.org/aas/motor","endpoints":[{"protocolInformation":{"href":"https://localhost:1234/api/v3.0/aas","endpointProtocol":"HTTP","endpointProtocolVersion":["1.1"]},"interface":"AAS-3.0"},{"protocolInformation":{"href":"opc.tcp://localhost:4840"},"interface":"AAS-3.0"},{"protocolInformation":{"href":"https://localhost:5678","endpointProtocol":"HTTP","endpointProtocolVersion":["1.1"],"subprotocol":"OPC UA Basic SOAP","subprotocolBody":"ns=2;s=MyAAS","subprotocolBodyEncoding":"application/soap+xml"},"interface":"AAS-3.0"}]} allOf: - $ref: '#/components/schemas/Descriptor' - properties: @@ -1022,18 +1046,17 @@ components: assetType: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string endpoints: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Endpoint' globalAssetId: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string idShort: maxLength: 128 @@ -1041,16 +1064,14 @@ components: id: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string specificAssetIds: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SpecificAssetId' submodelDescriptors: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SubmodelDescriptor' Descriptor: @@ -1058,50 +1079,57 @@ components: properties: description: type: array - maxItems: 10000 items: $ref: '#/components/schemas/LangStringTextType' displayName: type: array - maxItems: 10000 items: $ref: '#/components/schemas/LangStringNameType' - example: { "endpoints": [ { "protocolInformation": { "endpointAddress": "https://localhost:1234", "endpointProtocolVersion": "1.1" }, "interface": "AAS-1.0" }, { "protocolInformation": { "endpointAddress": "opc.tcp://localhost:4840" }, "interface": "AAS-1.0" }, { "protocolInformation": { "endpointAddress": "https://localhost:5678", "endpointProtocolVersion": "1.1", "subprotocol": "OPC UA Basic SOAP", "subprotocolBody": "ns=2;s=MyAAS", "subprotocolBodyEncoding": "application/soap+xml" }, "interface": "AAS-1.0" } ] } + extensions: + minItems: 1 + type: array + items: + $ref: '#/components/schemas/Extension' + example: {"endpoints":[{"protocolInformation":{"href":"https://localhost:1234/api/v3.0/aas","endpointProtocolVersion":["1.1"]},"interface":"AAS-3.0"},{"protocolInformation":{"href":"opc.tcp://localhost:4840"},"interface":"AAS-3.0"},{"protocolInformation":{"href":"https://localhost:5678","endpointProtocolVersion":["1.1"],"subprotocol":"OPC UA Basic SOAP","subprotocolBody":"ns=2;s=MyAAS","subprotocolBodyEncoding":"application/soap+xml"},"interface":"AAS-3.0"}]} LangStringTextType: - type: object allOf: - $ref: '#/components/schemas/AbstractLangString' - properties: text: + ## TODO: Diff between current AAS Registry OpenAPI and v3.0.2 (type is not present in v3.0.2) type: string maxLength: 1023 AbstractLangString: + required: + - language + - text type: object properties: language: - pattern: "^(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){2})?|[a-zA-Z]{4}|[a-zA-Z]{5,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){1,8})+)?|[xX](-([a-zA-Z0-9]){1,8})+|((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)))$" + pattern: "^(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4}|[a-zA-Z]{5,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){1,8})+)?|[xX](-([a-zA-Z0-9]){1,8})+|((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)))$" type: string text: minLength: 0 - pattern: "^([\\t\\n\\r-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string LangStringNameType: - type: object allOf: - $ref: '#/components/schemas/AbstractLangString' - properties: text: + ## TODO: Diff between current AAS Registry OpenAPI and v3.0.2 (type is not present in v3.0.2) type: string maxLength: 128 Extension: - type: object allOf: - $ref: '#/components/schemas/HasSemantics' - - properties: + - required: + - name + properties: name: maxLength: 128 minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string valueType: $ref: '#/components/schemas/DataTypeDefXsd' @@ -1110,7 +1138,6 @@ components: refersTo: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Reference' HasSemantics: @@ -1121,22 +1148,21 @@ components: supplementalSemanticIds: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Reference' Reference: - type: object - allOf: - - $ref: '#/components/schemas/ReferenceParent' - ReferenceParent: + required: + - keys + - type type: object properties: type: $ref: '#/components/schemas/ReferenceTypes' + referredSemanticId: + $ref: '#/components/schemas/Reference' keys: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Key' ReferenceTypes: @@ -1145,6 +1171,9 @@ components: - ExternalReference - ModelReference Key: + required: + - type + - value type: object properties: type: @@ -1152,7 +1181,7 @@ components: value: maxLength: 2000 minLength: 1 - pattern: "^([\\t\\n\\r-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string KeyTypes: type: string @@ -1215,7 +1244,6 @@ components: - xs:unsignedLong - xs:unsignedShort AdministrativeInformation: - type: object allOf: - $ref: '#/components/schemas/HasDataSpecification' - properties: @@ -1224,21 +1252,21 @@ components: allOf: - maxLength: 4 minLength: 1 - # - pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - # - pattern: "^(0|[1-9][0-9]*)$" + - pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + - pattern: "^(0|[1-9][0-9]*)$" revision: type: string allOf: - maxLength: 4 minLength: 1 - # - pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - # - pattern: "^(0|[1-9][0-9]*)$" + - pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + - pattern: "^(0|[1-9][0-9]*)$" creator: $ref: '#/components/schemas/Reference' templateId: maxLength: 2000 minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string HasDataSpecification: type: object @@ -1246,76 +1274,77 @@ components: embeddedDataSpecifications: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/EmbeddedDataSpecification' EmbeddedDataSpecification: + required: + - dataSpecification + - dataSpecificationContent type: object properties: - dataSpecification: - $ref: '#/components/schemas/Reference' dataSpecificationContent: $ref: '#/components/schemas/DataSpecificationContent_choice' + dataSpecification: + $ref: '#/components/schemas/Reference' DataSpecificationContent_choice: - type: object oneOf: - $ref: '#/components/schemas/DataSpecificationIec61360' DataSpecificationIec61360: - type: object allOf: - $ref: '#/components/schemas/DataSpecificationContent' - - properties: + - required: + - preferredName + properties: preferredName: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/LangStringPreferredNameTypeIec61360' shortName: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/LangStringShortNameTypeIec61360' unit: minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string unitId: $ref: '#/components/schemas/Reference' sourceOfDefinition: minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string symbol: minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string dataType: $ref: '#/components/schemas/DataTypeIec61360' definition: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/LangStringDefinitionTypeIec61360' valueFormat: minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string valueList: $ref: '#/components/schemas/ValueList' value: maxLength: 2000 minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string levelType: $ref: '#/components/schemas/LevelType' modelType: - # pattern: DataSpecificationIec61360 + pattern: ^DataSpecificationIec61360$ type: string DataSpecificationContent: + required: + - modelType type: object properties: modelType: @@ -1342,14 +1371,12 @@ components: - SubmodelElementCollection - SubmodelElementList LangStringPreferredNameTypeIec61360: - type: object allOf: - $ref: '#/components/schemas/AbstractLangString' - properties: text: maxLength: 255 LangStringShortNameTypeIec61360: - type: object allOf: - $ref: '#/components/schemas/AbstractLangString' - properties: @@ -1378,32 +1405,40 @@ components: - TIME - TIMESTAMP LangStringDefinitionTypeIec61360: - type: object allOf: - $ref: '#/components/schemas/AbstractLangString' - properties: text: maxLength: 1023 ValueList: + required: + - valueReferencePairs type: object properties: valueReferencePairs: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/ValueReferencePair' ValueReferencePair: + required: + - value + - valueId type: object properties: value: maxLength: 2000 minLength: 1 - # pattern: "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string valueId: $ref: '#/components/schemas/Reference' LevelType: + required: + - max + - min + - nom + - typ type: object properties: min: @@ -1415,10 +1450,10 @@ components: max: type: boolean Endpoint: - type: object required: - interface - - protocolInformation + # - protocolInformation + type: object properties: interface: maxLength: 128 @@ -1426,6 +1461,8 @@ components: protocolInformation: $ref: '#/components/schemas/ProtocolInformation' ProtocolInformation: + required: + - href type: object properties: href: @@ -1436,7 +1473,6 @@ components: type: string endpointProtocolVersion: type: array - maxItems: 10000 items: maxLength: 128 type: string @@ -1444,7 +1480,7 @@ components: maxLength: 128 type: string subprotocolBody: - maxLength: 2048 + maxLength: 128 type: string subprotocolBodyEncoding: maxLength: 128 @@ -1452,7 +1488,6 @@ components: securityAttributes: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/ProtocolInformation_securityAttributes' AssetLink: @@ -1468,26 +1503,28 @@ components: maxLength: 2000 pattern: "^([\\t\\n\\r -\ud7ff\ue000-\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" SpecificAssetId: - type: object allOf: - $ref: '#/components/schemas/HasSemantics' - - properties: + - required: + - name + - value + properties: name: maxLength: 64 minLength: 1 - pattern: "^([\\t\\n\\r-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string value: maxLength: 2000 minLength: 1 - pattern: "^([\\t\\n\\r-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string externalSubjectId: $ref: '#/components/schemas/Reference' - required: - - name - - value SubmodelDescriptor: + required: + - endpoints + - id type: object properties: administration: @@ -1495,7 +1532,6 @@ components: endpoints: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Endpoint' idShort: @@ -1504,17 +1540,16 @@ components: id: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string semanticId: $ref: '#/components/schemas/Reference' supplementalSemanticId: minItems: 1 type: array - maxItems: 10000 items: $ref: '#/components/schemas/Reference' - example: {"endpoints": [{"interface": "interfaceNameExample","protocolInformation": {"href": "endpointAddressExample","endpointProtocol": "endpointProtocolExample","endpointProtocolVersion": [ "e"],"subprotocol": "subprotocolExample","subprotocolBody": "subprotocolBodyExample","subprotocolBodyEncoding": "subprotocolBodyExample","securityAttributes": [{"type": "NONE","key": "Security Attribute key","value": "Security Attribute value" }]}}],"idShort": "idShortExample","id": "341f63de-728a-4b6d-9c72-c0d9ba4f8c7d","semanticId": {"type": "ExternalReference","keys": [{"type": "Submodel","value": "semanticIdExample"}]},"description": [{"language": "de","text": "hello text"},{"language": "en","text": "hello s"}]} + example: {"id":"https://admin-shell.io/zvei/nameplate/1/0/Nameplate","endpoints":[{"protocolInformation":{"href":"https://localhost:1234/api/v3.0/submodel","endpointProtocol":"HTTP","endpointProtocolVersion":["1.1"]},"interface":"AAS-3.0"},{"protocolInformation":{"href":"opc.tcp://localhost:4840"},"interface":"AAS-3.0"},{"protocolInformation":{"href":"https://localhost:5678","endpointProtocol":"HTTP","endpointProtocolVersion":["1.1"],"subprotocol":"OPC UA Basic SOAP","subprotocolBody":"ns=2;s=MyAAS","subprotocolBodyEncoding":"application/soap+xml"},"interface":"AAS-3.0"}]} allOf: - $ref: '#/components/schemas/Descriptor' Result: @@ -1522,7 +1557,6 @@ components: properties: messages: type: array - maxItems: 10000 items: $ref: '#/components/schemas/Message' Message: @@ -1550,14 +1584,12 @@ components: 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: string GetSubmodelDescriptorsResult: - type: object allOf: - $ref: '#/components/schemas/PagedResult' - type: object properties: result: type: array - maxItems: 10000 items: $ref: '#/components/schemas/SubmodelDescriptor' ServiceDescription: @@ -1566,7 +1598,6 @@ components: profiles: minItems: 1 type: array - maxItems: 10000 items: type: string enum: @@ -1588,8 +1619,9 @@ components: - https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-003 - https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-004 - https://admin-shell.io/aas/API/3/0/ConceptDescriptionServiceSpecification/SSP-001 + example: ["https://admin-shell.io/aas/API/3/0/AssetAdministrationShellServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/AssetAdministrationShellServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-003","https://admin-shell.io/aas/API/3/0/AasxFileServerServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelRegistryServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/SubmodelRegistryServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/DiscoveryServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-001","https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-003","https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-004","https://admin-shell.io/aas/API/3/0/ConceptDescriptionServiceSpecification/SSP-001"] description: "The Description object enables servers to present their capabilities to the clients, in particular which profiles they implement. At least one defined profile is required. Additional, proprietary attributes might be included. Nevertheless, the server must not expect that a regular client understands them." - example: { "profiles": ["https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-002", "https://admin-shell.io/aas/API/3/0/SubmodelRegistryServiceSpecification/SSP-002"] } + example: {"profiles": ["https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-002","https://admin-shell.io/aas/API/3/0/SubmodelRegistryServiceSpecification/SSP-002"]} PagedResult_paging_metadata: type: object properties: @@ -1597,6 +1629,10 @@ components: type: string example: wJlCDLIl6KTWypN7T6vc6nWEmEYe99Hjf1XY1xmqV-M=# ProtocolInformation_securityAttributes: + required: + - key + - type + - value type: object properties: type: @@ -1622,6 +1658,15 @@ components: required: - submodelEndpointUrl additionalProperties: false + inline_response_200: + allOf: + - $ref: '#/components/schemas/PagedResult' + - type: object + properties: + result: + type: array + items: + type: string responses: bad-request: description: "Bad Request, e.g. the request parameters of the format of the request body is wrong." @@ -1690,7 +1735,7 @@ components: schema: maxLength: 2000 minLength: 1 - pattern: "^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$" + pattern: "^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" type: string AssetAdministrationShellIdentifier: name: aasIdentifier @@ -1701,7 +1746,6 @@ components: explode: false schema: type: string - # format: byte SubmodelIdentifier: name: submodelIdentifier in: path @@ -1717,7 +1761,6 @@ components: schema: type: string description: Incoming external_subject_id/bpn - # format: byte examples: lookup-shells-by-aas-identifier-post: value: diff --git a/backend/src/test/java/org/eclipse/tractusx/semantics/registry/AssetAdministrationShellApiTest.java b/backend/src/test/java/org/eclipse/tractusx/semantics/registry/AssetAdministrationShellApiTest.java index f0310e03..1697bbcd 100644 --- a/backend/src/test/java/org/eclipse/tractusx/semantics/registry/AssetAdministrationShellApiTest.java +++ b/backend/src/test/java/org/eclipse/tractusx/semantics/registry/AssetAdministrationShellApiTest.java @@ -25,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.UUID; @@ -32,6 +33,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.tractusx.semantics.aas.registry.model.AssetAdministrationShellDescriptor; import org.eclipse.tractusx.semantics.aas.registry.model.AssetLink; +import org.eclipse.tractusx.semantics.aas.registry.model.Endpoint; import org.eclipse.tractusx.semantics.aas.registry.model.LangStringTextType; import org.eclipse.tractusx.semantics.aas.registry.model.SpecificAssetId; import org.eclipse.tractusx.semantics.aas.registry.model.SubmodelDescriptor; @@ -86,7 +88,7 @@ public void testCreateShellExpectRegexError() throws Exception { ) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isBadRequest()) - .andExpect( jsonPath( "$.messages[0].text", is( "must match \"^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\x{00010000}-\\x{0010FFFF}]*$\"" ) ) ); + .andExpect( jsonPath( "$.messages[0].text", is( "must match \"^([\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$\"" ) ) ); } @Test @@ -1152,12 +1154,8 @@ public void test_Creating_a_new_Asset_Administration_Shell_Descriptor_with_uniqu removedAllShells(); AssetAdministrationShellDescriptor shellPayload = TestUtil.createCompleteAasDescriptor(); - SubmodelDescriptor submodelDescriptor = new SubmodelDescriptor(); - //Setting duplicate id short - submodelDescriptor.setIdShort(shellPayload.getSubmodelDescriptors().get( 0 ).getIdShort()); - - //Adding duplicate submodel which contains duplicate idshort - shellPayload.getSubmodelDescriptors().add( submodelDescriptor); + //Duplicate submodel to simulate duplicate idshort + shellPayload.getSubmodelDescriptors().add( shellPayload.getSubmodelDescriptors().get( 0 ) ); //When & Then