├── .dockerignore ├── .gitattributes ├── .github └── workflows │ └── build-and-publish-docker-images.yml ├── .gitignore ├── .swagger-codegen-ignore ├── .swagger-codegen └── VERSION ├── AAS API on Azure.sln ├── Assets ├── AASXFileRefArchitecture.vsdx └── images │ └── AzureIIoTHeroscenarioRefArch.png ├── CODE_OF_CONDUCT.md ├── LICENSE ├── NuGet.Config ├── README.md ├── SECURITY.md ├── build.bat ├── build.sh ├── scripts ├── arm-bicep-azuredeployment │ ├── aasRepositoryAdt.bicep │ ├── aascosmosdbregistry.bicep │ ├── aasredisregistry.bicep │ ├── createAASRegistryADAppRegIfNotExits.ps1 │ ├── deployAASRegistry.ps1 │ ├── deployAasRepository.ps1 │ └── modules │ │ ├── aasapiappserviceplan.bicep │ │ ├── aasapimgmt.bicep │ │ ├── aasservicesconfig.bicep │ │ ├── aasserviceslog.bicep │ │ ├── azureDigitalTwins.bicep │ │ ├── containerRegistry.bicep │ │ └── repositoryContainerAppAdt.bicep ├── azuredeployment │ ├── aasapiservicestdroles.json │ ├── createAzureDigitalTwinsInstance.ps1 │ ├── createAzureRedisCacheDBForRegistryServer.ps1 │ ├── createAzureStorageForAASXFileServer.ps1 │ ├── createWebApiAppForService.ps1 │ └── deployAzureInfrastructure.ps1 └── dockerbuilds │ ├── buildRegistryACRTask.ps1 │ └── buildRegistryDockerImage.ps1 ├── src ├── AAS ADT SDK Tests │ ├── AAS ADT SDK Tests.csproj │ ├── AAS ADT SDK Tests.csproj.DotSettings │ ├── AutoMapper │ │ ├── AdtAssetAdministrationShellProfileTests.cs │ │ ├── AdtIec61360ProfileTests.cs │ │ ├── AdtReferenceProfileTests.cs │ │ ├── AdtSubmodelElementProfileTests.cs │ │ └── AdtSubmodelProfileTests.cs │ ├── Connectors │ │ ├── AADTAASRepoTests.cs │ │ ├── AasDeleteAdtTests.cs │ │ ├── AasUpdateAdtTests.cs │ │ ├── AasWriteAssetAdministrationShellTests.cs │ │ ├── AasWriteBaseTests.cs │ │ ├── AasWriteConnectorForAdtCommunicationTests.cs │ │ ├── AasWriteSubmodelElementsTests.cs │ │ ├── AasWriteSubmodelTests.cs │ │ └── AdtTwinFactoryTests.cs │ ├── CustomDTSerializationTests.cs │ ├── Usings.cs │ └── appsettings.tests.json ├── AAS ADT SDK │ ├── AAS ADT SDK.csproj │ ├── AAS ADT SDK.csproj.DotSettings │ ├── AdtAasOntology.cs │ ├── AutoMapper │ │ ├── AdtAssetAdministrationShellProfile.cs │ │ ├── AdtBaseProfile.cs │ │ ├── AdtIdentifiableProfile.cs │ │ ├── AdtIec61360Profile.cs │ │ ├── AdtReferableProfile.cs │ │ ├── AdtReferenceProfile.cs │ │ ├── AdtSubmodelElementProfile.cs │ │ └── AdtSubmodelProfile.cs │ ├── Connectors │ │ ├── ADTAASRepo.cs │ │ ├── AasDeleteAdt.cs │ │ ├── AasUpdateAdt.cs │ │ ├── AasWriteAssetAdministrationShell.cs │ │ ├── AasWriteBase.cs │ │ ├── AasWriteConnectorForAdtCommunication.cs │ │ ├── AasWriteSubmodel.cs │ │ ├── AasWriteSubmodelElements.cs │ │ ├── AdtTwinFactory.cs │ │ ├── IADTAASRepo.cs │ │ ├── IAasDeleteAdt.cs │ │ ├── IAasUpdateAdt.cs │ │ ├── IAasWriteAssetAdministrationShell.cs │ │ ├── IAasWriteBase.cs │ │ ├── IAasWriteConnectorForAdtCommunication.cs │ │ ├── IAasWriteSubmodel.cs │ │ ├── IAasWriteSubmodelElements.cs │ │ └── IAdtTwinFactory.cs │ ├── Exceptions │ │ └── ImportException.cs │ └── Models │ │ ├── AdtAas.cs │ │ ├── AdtAdministration.cs │ │ ├── AdtAssetInformation.cs │ │ ├── AdtBase.cs │ │ ├── AdtConceptDescription.cs │ │ ├── AdtDataSpecification.cs │ │ ├── AdtDataSpecificationContent.cs │ │ ├── AdtDataSpecificationIEC61360.cs │ │ ├── AdtFile.cs │ │ ├── AdtHasKind.cs │ │ ├── AdtIdentifiable.cs │ │ ├── AdtKey.cs │ │ ├── AdtLanguageString.cs │ │ ├── AdtProperty.cs │ │ ├── AdtReferable.cs │ │ ├── AdtReference.cs │ │ ├── AdtRelationship.cs │ │ ├── AdtSubmodel.cs │ │ ├── AdtSubmodelElement.cs │ │ └── AdtSubmodelElementCollection.cs ├── aas-aasxfile-service-tests │ ├── AAS AASX File Service Tests.csproj │ ├── AASXFileServerTests.cs │ ├── Resources │ │ └── 01_Festo.aasx │ └── appsettings.tests.json ├── aas-aasxfile-service │ ├── AAS AASX File Service.csproj │ ├── AASAASXFile.cs │ └── AzureBlobImpl │ │ └── AzureBlobAASXFileService.cs ├── aas-api-models │ ├── AAS API Models.csproj │ ├── Interfaces │ │ ├── AAS.cs │ │ ├── AASXFileServer.cs │ │ ├── BasicDiscovery.cs │ │ ├── Registry.cs │ │ ├── ShellRepository.cs │ │ ├── SubmodelRegistry.cs │ │ └── Submodels.cs │ └── Models │ │ ├── AdministrativeInformation.cs │ │ ├── AssetAdministrationShell.cs │ │ ├── AssetAdministrationShellDescriptor.cs │ │ ├── AssetInformation.cs │ │ ├── AssetKind.cs │ │ ├── ConceptDescription.cs │ │ ├── DataSpecificationContent.cs │ │ ├── DataTypeDefXsd.cs │ │ ├── Descriptor.cs │ │ ├── EmbeddedDataSpecification.cs │ │ ├── Endpoint.cs │ │ ├── Environment.cs │ │ ├── ExecutionState.cs │ │ ├── Extension.cs │ │ ├── HasDataSpecification.cs │ │ ├── HasExtensions.cs │ │ ├── HasKind.cs │ │ ├── HasSemantics.cs │ │ ├── IdShortPathAttachmentBody.cs │ │ ├── Identifiable.cs │ │ ├── IdentifierKeyValuePair.cs │ │ ├── Key.cs │ │ ├── KeyTypes.cs │ │ ├── LangString.cs │ │ ├── Message.cs │ │ ├── ModelType.cs │ │ ├── ModelingKind.cs │ │ ├── OperationRequest.cs │ │ ├── OperationResult.cs │ │ ├── OperationVariable.cs │ │ ├── PackageDescription.cs │ │ ├── PackagesBody.cs │ │ ├── PackagesPackageIdBody.cs │ │ ├── ProtocolInformation.cs │ │ ├── Qualifiable.cs │ │ ├── Qualifier.cs │ │ ├── QualifierKind.cs │ │ ├── Referable.cs │ │ ├── Reference.cs │ │ ├── ReferenceParent.cs │ │ ├── ReferenceTypes.cs │ │ ├── Resource.cs │ │ ├── Result.cs │ │ ├── SpecificAssetId.cs │ │ ├── Submodel.cs │ │ ├── SubmodelDescriptor.cs │ │ └── SubmodelElement.cs ├── aas-api-repository-adt-tests │ ├── ADTAASRepoServiceTests.cs │ ├── ADTAASRepoStandardTests.cs │ ├── AasRepositoryAdtTests.csproj │ ├── AasRepositoryAdtTests.csproj.DotSettings │ ├── ModelFactories │ │ ├── ADTAASModelFactoryTests.cs │ │ ├── AdtDefinitionsAndSemanticsModelFactoryTests.cs │ │ ├── AdtSubmodelElementModelFactoryTests.cs │ │ └── AdtSubmodelModelFactoryTests.cs │ ├── Usings.cs │ └── appsettings.tests.json ├── aas-api-repository-adt │ ├── ADTAASRepository.cs │ ├── AasRepositoryAdt.csproj │ ├── AasRepositoryAdt.csproj.DotSettings │ ├── AdtSubmodelRepository.cs │ ├── Common │ │ └── AdtDataTransferObjects.cs │ ├── Connectors │ │ ├── AdtAasConnector.cs │ │ ├── AdtSubmodelConnector.cs │ │ ├── IAdtAasConnector.cs │ │ └── IAdtSubmodelConnector.cs │ ├── Exceptions │ │ └── AasAdtExceptions.cs │ └── ModelFactories │ │ ├── ADTAASModelFactory.cs │ │ ├── AdtDefinitionsAndSemanticsModelFactory.cs │ │ ├── AdtSubmodelElementFactory.cs │ │ ├── AdtSubmodelModelFactory.cs │ │ ├── IAdtDefinitionsAndSemanticsModelFactory.cs │ │ ├── IAdtSubmodelElementFactory.cs │ │ └── IAdtSubmodelModelFactory.cs ├── aas-api-webapp-aasxfile │ ├── .gitignore │ ├── AAS WebApp AASX File Server.csproj │ ├── Attributes │ │ └── ValidateModelStateAttribute.cs │ ├── Controllers │ │ └── AASXFileServerInterfaceApi.cs │ ├── Dockerfile │ ├── Filters │ │ ├── BasePathFilter.cs │ │ └── GeneratePathParamsValidationFilter.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── web.config │ └── wwwroot │ │ ├── README.md │ │ ├── index.html │ │ ├── swagger-original-file.json │ │ ├── swagger-original.json │ │ └── web.config ├── aas-api-webapp-discovery │ ├── AAS WebApp Discovery.csproj │ ├── Attributes │ │ └── ValidateModelStateAttribute.cs │ ├── Controllers │ │ └── AssetAdministrationShellBasicDiscoveryApi.cs │ ├── Dockerfile │ ├── Filters │ │ ├── BasePathFilter.cs │ │ └── GeneratePathParamsValidationFilter.cs │ ├── Models │ │ ├── IdentifierKeyValuePairModelBinder.cs │ │ └── IdentifierKeyValuePairModelBinderProvider.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── web.config │ └── wwwroot │ │ ├── README.md │ │ ├── index.html │ │ ├── swagger-original-discovery.json │ │ ├── swagger-original.json │ │ └── web.config ├── aas-api-webapp-full │ ├── .config │ │ └── dotnet-tools.json │ ├── .gitignore │ ├── AAS WebApp full.csproj │ ├── Attributes │ │ └── ValidateModelStateAttribute.cs │ ├── Controllers │ │ ├── AASXFileServerInterfaceApi.cs │ │ ├── AssetAdministrationShellBasicDiscoveryApi.cs │ │ ├── AssetAdministrationShellInterfaceApi.cs │ │ ├── AssetAdministrationShellRegistryInterfaceApi.cs │ │ ├── AssetAdministrationShellRepositoryInterfaceApi.cs │ │ ├── AssetAdministrationShellSerializationInterfaceApi.cs │ │ ├── ConceptDescriptionRepositoryInterfaceApi.cs │ │ ├── DescriptorInterfaceApi.cs │ │ ├── SubmodelInterfaceApi.cs │ │ ├── SubmodelRegistryInterfaceApi.cs │ │ └── SubmodelRepositoryInterfaceApi.cs │ ├── Dockerfile │ ├── Filters │ │ ├── BasePathFilter.cs │ │ └── GeneratePathParamsValidationFilter.cs │ ├── Models │ │ ├── IdentifierKeyValuePairModelBinder.cs │ │ └── IdentifierKeyValuePairModelBinderProvider.cs │ ├── Program.cs │ ├── Properties │ │ ├── ServiceDependencies │ │ │ ├── hack2021aasapi - FTP │ │ │ │ └── profile.arm.json │ │ │ └── hack2021aasapi - Web Deploy │ │ │ │ └── profile.arm.json │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── web.config │ └── wwwroot │ │ ├── README.md │ │ ├── index.html │ │ ├── swagger-original.json │ │ └── web.config ├── aas-api-webapp-registry │ ├── AAS WebApp Registry.csproj │ ├── Attributes │ │ └── ValidateModelStateAttribute.cs │ ├── Controllers │ │ ├── AssetAdministrationShellRegistryAPIApi.cs │ │ ├── AssetAdministrationShellRegistryAPIExtApi.cs │ │ └── SubmodelRegistryAPIApi.cs │ ├── Dockerfile │ ├── Filters │ │ ├── BasePathFilter.cs │ │ └── GeneratePathParamsValidationFilter.cs │ ├── Models │ │ ├── IdentifierKeyValuePairModelBinder.cs │ │ └── IdentifierKeyValuePairModelBinderProvider.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── web.config │ └── wwwroot │ │ ├── README.md │ │ ├── index.html │ │ ├── swagger-original-file.json │ │ ├── swagger-original.json │ │ └── web.config ├── aas-api-webapp-repository │ ├── .gitignore │ ├── AAS WebApp Repository.csproj │ ├── AAS WebApp Repository.csproj.DotSettings │ ├── Attributes │ │ └── ValidateModelStateAttribute.cs │ ├── Controllers │ │ ├── AasRepositoryApi.cs │ │ ├── AssetAdministrationShellRepositoryApi.cs │ │ └── SubmodelRepositoryApi.cs │ ├── Dockerfile │ ├── Filters │ │ ├── BasePathFilter.cs │ │ └── GeneratePathParamsValidationFilter.cs │ ├── Mapper │ │ ├── AasAttributeExtensionsWithJObject.cs │ │ ├── AutoMapper │ │ │ └── DataTypeDefXsdProfile.cs │ │ ├── JObjectToAasObjectMapperStrategy.cs │ │ └── JObjectToPropertyMapper.cs │ ├── Models │ │ ├── IdentifierKeyValuePairModelBinder.cs │ │ └── IdentifierKeyValuePairModelBinderProvider.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.json │ ├── libman.json │ ├── web.config │ └── wwwroot │ │ ├── README.md │ │ ├── index.html │ │ ├── swagger-original.json │ │ └── web.config ├── aas-discovery-service │ ├── AAS Discovery Service.csproj │ ├── AASDiscovery.cs │ ├── AASDiscoveryFactory.cs │ └── ADTImpl │ │ └── ADTAASDiscovery.cs ├── aas-registry-service-tests │ ├── AAS Registry Service Tests.csproj │ ├── AASRegistryServiceTests.cs │ ├── CosmosDBAASRegistryServiceTests.cs │ ├── Descriptor samples │ │ ├── sampleAASDesc.json │ │ ├── test001AASDesc.json │ │ ├── test001SubmodelDesc.json │ │ ├── testAASDescs.json │ │ └── testSubmodelDescs.json │ └── appsettings.tests.json ├── aas-registry-service │ ├── AAS Registry Service.csproj │ ├── AASRegistry.cs │ ├── Cache.cs │ ├── CosmosDBImpl │ │ ├── CosmosDBAASRegistry.cs │ │ ├── DBAssetAdministrationShellDescriptor.cs │ │ └── DBSubmodelDescriptor.cs │ ├── Program.cs │ └── RedisImpl │ │ └── RedisAASRegistry.cs ├── aas-repository-tests │ └── AAS Repository Tests.csproj ├── aas-repository │ ├── AAS Repository.csproj │ ├── AASRepository.cs │ ├── ISubmodelRepository.cs │ └── Program.cs ├── aas-services-support-tests │ ├── AAS Services Support Tests.csproj │ ├── Usings.cs │ └── app.config └── aas-services-support │ ├── AAS Services Support.csproj │ ├── AAS Services Support.csproj.DotSettings │ ├── AASServiceException.cs │ └── ADT Support │ ├── ADTConstants.cs │ ├── ADTOperationsResult.cs │ ├── AbstractADTAASService.cs │ └── Clients │ ├── AzureDigitalTwinsHttpClient.cs │ ├── DigitalTwinsClientFactory.cs │ └── IAzureDigitalTwinsHttpClient.cs └── tools ├── README.md ├── aas-model-generator ├── Program.cs └── aas-model-generator.csproj ├── aasx command line.md ├── aasx-cmdline-tests ├── AASX Package Command line Tests.csproj ├── ADTAASRepoTests.cs ├── AbstractTestSupport.cs ├── SimpleAASXImportTests.cs ├── StandardSamplesImportTests.cs └── appsettings.tests.json └── aasx-cmdline ├── AASUtils.cs ├── AASX Package Command line.csproj ├── AASXImporter.cs ├── ADTAASOntology.cs ├── ADTAASRepo.cs ├── ADTAASXPackageImporter.cs ├── AbstractADTCommand.cs ├── IAASRepo.cs ├── IAASXInspector.cs ├── Program.cs ├── Properties └── launchSettings.json ├── Resources ├── Samples │ ├── 01_Festo Sample │ │ ├── 01_Festo ADTExplorer Export.json │ │ ├── 01_Festo in ADT.jpg │ │ └── wwwcompanycomidsaas9350_1162_7091_7335.aas.xml │ ├── 02_Bosch_Sample │ │ └── 02_Bosch ADTExplorer Export.json │ ├── 07_PhoenixContact_Sample │ │ ├── 07_PhoenixContact ADTExplorer Export.json │ │ └── 07_PhoenixContact in ADT.jpg │ ├── 08_SchneiderElectric_Sample │ │ ├── 08_SchneiderElectric ADTExplorer Export.json │ │ └── 08_SchneiderElectric in ADT.jpg │ └── 15_Siemens │ │ ├── 15_Siemens ADTExplorer Export.json │ │ └── 15_Siemens in ADT.jpg ├── Schemas │ └── schemaV201 │ │ ├── AAS.xsd │ │ ├── AAS_ABAC.xsd │ │ ├── IEC61360.xsd │ │ └── aas.json └── Test │ └── sample01.aas.xml ├── StdAASXInspector.cs └── appsettings.json /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | 3.0.27 -------------------------------------------------------------------------------- /Assets/AASXFileRefArchitecture.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/Assets/AASXFileRefArchitecture.vsdx -------------------------------------------------------------------------------- /Assets/images/AzureIIoTHeroscenarioRefArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/Assets/images/AzureIIoTHeroscenarioRefArch.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jürgen Mayrbäurl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | :: Build all AAS API Servers 2 | :: 3 | 4 | @echo off 5 | 6 | :: Build AASX File Server 7 | 8 | dotnet restore "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" 9 | dotnet build "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" -c Debug 10 | echo Now, run the following to start the project: dotnet run -p "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" --launch-profile web. 11 | echo. 12 | 13 | docker build -f "src\aas-api-webapp-aasxfile\Dockerfile" --force-rm -t aas-aasxfile-server:latest . 14 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Build all AAS API Servers 4 | # 5 | 6 | dotnet restore "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" && \ 7 | dotnet build "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" -c Debug && \ 8 | echo "Now, run the following to start the project: dotnet run -p 'src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj' --launch-profile web" 9 | 10 | docker build -f "src/aas-api-webapp-aasxfile/Dockerfile" --force-rm -t aas-aasxfile-server:latest . && \ 11 | echo "Now, run with: docker run -d -p 4567:80 aas-aasxfile-server:latest" 12 | -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/aasRepositoryAdt.bicep: -------------------------------------------------------------------------------- 1 | 2 | @description('Location of all resources') 3 | param location string = resourceGroup().location 4 | 5 | @description('Azure Digital Twins Service name, max length 44 characters') 6 | param adtName string = 'aasrepositoryadt-${uniqueString(resourceGroup().id)}' 7 | 8 | @description('Azure Container App account name, max length 44 characters') 9 | 10 | param dockerImageName string 11 | @description('The IP Address that will be allowed to access the AAS repository API') 12 | param ipAddress string 13 | 14 | 15 | module adt 'modules/azureDigitalTwins.bicep'= { 16 | name: 'adtDeploy' 17 | scope: resourceGroup() 18 | params: { 19 | adtName: adtName 20 | location: location 21 | } 22 | } 23 | 24 | module containerApps 'modules/repositoryContainerAppAdt.bicep' = { 25 | name: 'containerApps' 26 | scope: resourceGroup() 27 | params: { 28 | location: location 29 | adtServiceUrl: 'https://${adt.outputs.hostName}' 30 | imageName: dockerImageName 31 | ipAddress: ipAddress 32 | } 33 | } 34 | 35 | resource aksSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { 36 | name: guid(adt.name,containerApps.name, resourceGroup().id) 37 | properties: { 38 | principalId: containerApps.outputs.principalId 39 | principalType: 'ServicePrincipal' 40 | roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', 'bcd981a7-7f74-457b-83e1-cceb9e632ffe') //Azure Digital Twins Data Owner 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/aasredisregistry.bicep: -------------------------------------------------------------------------------- 1 | @description('Location of all resources') 2 | param location string = resourceGroup().location 3 | 4 | @description('Specify the name of the Azure Redis Cache to create.') 5 | param redisCacheName string = 'aasregistrydb-${uniqueString(resourceGroup().id)}' 6 | 7 | resource registrydb 'Microsoft.Cache/redis@2021-06-01' = { 8 | location: location 9 | name: redisCacheName 10 | tags: { 11 | WorkloadName: 'AAS API Services' 12 | DataClassification: 'General' 13 | Criticality: 'Medium' 14 | ApplicationName: 'AAS Registry' 15 | Env: 'Test' 16 | } 17 | properties: { 18 | redisVersion: '6' 19 | enableNonSslPort: false 20 | minimumTlsVersion: '1.2' 21 | sku: { 22 | capacity: 0 23 | family: 'C' 24 | name: 'Basic' 25 | } 26 | } 27 | } 28 | 29 | module config 'modules/aasservicesconfig.bicep' = { 30 | name: 'aasservicesconfig' 31 | params: { 32 | location: location 33 | } 34 | } 35 | 36 | module apimgmt 'modules/aasapimgmt.bicep' = { 37 | name: 'aasservicesapimgmt' 38 | params: { 39 | location: location 40 | } 41 | } -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/createAASRegistryADAppRegIfNotExits.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string] $appRegistrationName = 'aas-registryservice-test' 3 | ) 4 | 5 | #objectid=$(az ad app show --id $clientid --query objectId --output tsv) 6 | 7 | $appReg=$(az ad app list --filter "displayname eq '$appRegistrationName'" | ConvertFrom-Json) 8 | $clientID='' 9 | 10 | if ($appReg.length -eq 0) { 11 | Write-Host "No Azure AD App registration for '" $appRegistrationName "' found. Creating a new one now" 12 | 13 | $clientid=$(az ad app create --display-name $appRegistrationName --query appId --output tsv) 14 | } 15 | else { 16 | Write-Host "Found Azure AD App registration for '" $appRegistrationName "'." 17 | 18 | $clientid=$appReg[0].appId 19 | } 20 | 21 | Write-Host "Client ID = " $clientID 22 | 23 | # TODO: Add the 'access_as_user' scope 24 | 25 | # And give Azure CLI access to a API. See https://www.schaeflein.net/use-a-cli-to-get-an-access-token-for-your-aad-protected-web-api/ 26 | # by getting an access token like: az account get-access-token --resource api://f8ed554d-073a-49f8-971e-c6b3ca43e3d6 27 | 28 | return $clientID -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/deployAASRegistry.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string] $rg = 'aasapi-work-rg', 3 | [string] $dbType = 'CosmosDB', 4 | [string] $clientID, 5 | [string] $appRegistrationName = 'aas-registryservice-test' 6 | ) 7 | 8 | $clientID=$(.\createAASRegistryADAppRegIfNotExits.ps1 -appRegistrationName $appRegistrationName) 9 | 10 | if ($dbType -eq 'Redis') 11 | { 12 | az deployment group create --resource-group $rg --template-file .\aasredisregistry.bicep 13 | } 14 | else { 15 | Write-Output 'Deploying CosmosDB based AAS Registry' 16 | az deployment group create --resource-group $rg --template-file .\aascosmosdbregistry.bicep 17 | } -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/deployAasRepository.ps1: -------------------------------------------------------------------------------- 1 | 2 | param ( 3 | [string] $dcloc = "West Europe", 4 | [string] $rg = "rg-test-aasrepo", 5 | 6 | [string] $containerRegistryName = "acr$(New-Guid)".Replace("-","") 7 | ) 8 | 9 | $subscriptionResourceGroups=(az group list | ConvertFrom-Json) 10 | 11 | if (-Not $subscriptionResourceGroups.name.Contains($rg)) { 12 | Write-Host "Deploying ressource group" $rg 13 | az group create --name $rg --location $dcloc 14 | } 15 | 16 | Write-Host "Deploying Azure Services for functioning AAS Repository" 17 | 18 | $dockerImageName="ghcr.io/mm-mse/aasonazurerepo" 19 | 20 | $myIpAddress = (Invoke-WebRequest ifconfig.me/ip).Content.Trim() 21 | az deployment group create --resource-group $rg --template-file .\aasRepositoryAdt.bicep --parameters dockerImageName=$dockerImageName ipAddress=$myIpAddress 22 | -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/aasapiappserviceplan.bicep: -------------------------------------------------------------------------------- 1 | @description('Application Name') 2 | @maxLength(30) 3 | param applicationName string = 'aas-apiservices-${uniqueString(resourceGroup().id)}' 4 | 5 | @description('Location for all resources.') 6 | param location string = resourceGroup().location 7 | 8 | @allowed([ 9 | 'F1' 10 | 'D1' 11 | 'B1' 12 | 'B2' 13 | 'B3' 14 | 'S1' 15 | 'S2' 16 | 'S3' 17 | 'P1' 18 | 'P2' 19 | 'P3' 20 | 'P4' 21 | ]) 22 | @description('App Service Plan\'s pricing tier. Details at https://azure.microsoft.com/pricing/details/app-service/') 23 | param appServicePlanTier string = 'B1' 24 | 25 | @minValue(1) 26 | @maxValue(3) 27 | @description('App Service Plan\'s instance count') 28 | param appServicePlanInstances int = 2 29 | 30 | resource hostingPlan 'Microsoft.Web/serverfarms@2022-03-01' = { 31 | name: applicationName 32 | location: location 33 | kind: 'linux' 34 | properties: { 35 | reserved: true 36 | } 37 | sku: { 38 | name: appServicePlanTier 39 | capacity: appServicePlanInstances 40 | } 41 | tags: { 42 | WorkloadName: 'AAS API Services' 43 | DataClassification: 'General' 44 | Criticality: 'Medium' 45 | ApplicationName: 'AAS Common' 46 | Env: 'Test' 47 | } 48 | } 49 | 50 | output serverFarmId string = hostingPlan.id -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/aasapimgmt.bicep: -------------------------------------------------------------------------------- 1 | @description('The name of the API Management service instance') 2 | param apiManagementServiceName string = 'aasapiservice${uniqueString(resourceGroup().id)}' 3 | 4 | @description('The email address of the owner of the service') 5 | @minLength(1) 6 | param publisherEmail string = 'jurgenma@microsoft.com' 7 | 8 | @description('The name of the owner of the service') 9 | @minLength(1) 10 | param publisherName string = 'Juergen Mayrbaeurl' 11 | 12 | @description('The pricing tier of this API Management service') 13 | @allowed([ 14 | 'Developer' 15 | 'Standard' 16 | 'Premium' 17 | ]) 18 | param sku string = 'Standard' 19 | 20 | @description('The instance size of this API Management service.') 21 | @allowed([ 22 | 1 23 | 2 24 | ]) 25 | param skuCount int = 1 26 | 27 | @description('Location for all resources.') 28 | param location string = resourceGroup().location 29 | 30 | resource apiManagementService 'Microsoft.ApiManagement/service@2021-08-01' = { 31 | name: apiManagementServiceName 32 | location: location 33 | sku: { 34 | name: sku 35 | capacity: skuCount 36 | } 37 | identity: { 38 | type: 'SystemAssigned' 39 | } 40 | properties: { 41 | publisherEmail: publisherEmail 42 | publisherName: publisherName 43 | } 44 | tags: { 45 | WorkloadName: 'AAS API Services' 46 | DataClassification: 'General' 47 | Criticality: 'Medium' 48 | ApplicationName: 'AAS Common' 49 | Env: 'Test' 50 | } 51 | } -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/aasservicesconfig.bicep: -------------------------------------------------------------------------------- 1 | @description('Specifies the name of the App Configuration store.') 2 | param configStoreName string = 'aasconfig-${uniqueString(resourceGroup().id)}' 3 | 4 | @description('Specifies the Azure location where the app configuration store should be created.') 5 | param location string = resourceGroup().location 6 | 7 | resource configStore 'Microsoft.AppConfiguration/configurationStores@2021-10-01-preview' = { 8 | name: configStoreName 9 | location: location 10 | sku: { 11 | name: 'standard' 12 | } 13 | tags: { 14 | WorkloadName: 'AAS API Services' 15 | DataClassification: 'General' 16 | Criticality: 'Medium' 17 | ApplicationName: 'AAS Common' 18 | Env: 'Test' 19 | } 20 | } -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/aasserviceslog.bicep: -------------------------------------------------------------------------------- 1 | @description('Specifies the name of the App Configuration store.') 2 | param logWSName string = 'aaslogsws-${uniqueString(resourceGroup().id)}' 3 | 4 | @description('Specifies the Azure location where the app configuration store should be created.') 5 | param location string = resourceGroup().location 6 | 7 | resource aaslogs 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { 8 | name: logWSName 9 | location: location 10 | properties: { 11 | sku:{ 12 | name: 'PerGB2018' 13 | } 14 | } 15 | tags: { 16 | WorkloadName: 'AAS API Services' 17 | DataClassification: 'General' 18 | Criticality: 'Medium' 19 | ApplicationName: 'AAS Common' 20 | Env: 'Test' 21 | } 22 | } 23 | 24 | output logAnalyticsWorkspace string = logWSName -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/azureDigitalTwins.bicep: -------------------------------------------------------------------------------- 1 | 2 | @description('Location of all resources') 3 | param location string = resourceGroup().location 4 | 5 | @description('Azure Digital Twins Service name, max length 44 characters') 6 | param adtName string = 'aasrepositoryadt-${uniqueString(resourceGroup().id)}' 7 | 8 | @description('') 9 | resource aasAdt 'Microsoft.DigitalTwins/digitalTwinsInstances@2022-10-31'= { 10 | location: location 11 | name: toLower(adtName) 12 | properties: { 13 | privateEndpointConnections: [] 14 | publicNetworkAccess: 'Enabled' 15 | } 16 | } 17 | 18 | output hostName string = aasAdt.properties.hostName 19 | -------------------------------------------------------------------------------- /scripts/arm-bicep-azuredeployment/modules/containerRegistry.bicep: -------------------------------------------------------------------------------- 1 | @description('Location of all resources') 2 | param location string = resourceGroup().location 3 | 4 | @description('Max length 44 characters') 5 | param acrName string = 'aasonazurecr${uniqueString(resourceGroup().id)}' 6 | 7 | resource aasonazurecr 'Microsoft.ContainerRegistry/registries@2022-12-01' = { 8 | sku: { 9 | name: 'Basic' 10 | } 11 | name: acrName 12 | location: location 13 | tags: { 14 | } 15 | properties: { 16 | adminUserEnabled: true 17 | encryption: { 18 | status: 'disabled' 19 | } 20 | } 21 | } 22 | 23 | output acrId string = aasonazurecr.id 24 | -------------------------------------------------------------------------------- /scripts/azuredeployment/aasapiservicestdroles.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "allowedMemberTypes": [ 4 | "Application" 5 | ], 6 | "description": "Contributors have to right to read and write AAS objects", 7 | "displayName": "AAS Contributor", 8 | "isEnabled": true, 9 | "value": "AAS.ReadWrite" 10 | } 11 | ] -------------------------------------------------------------------------------- /scripts/azuredeployment/createAzureDigitalTwinsInstance.ps1: -------------------------------------------------------------------------------- 1 | # Create Azure Digital Twin instance for the Shell and Discovery service 2 | # uses the currently selected Azure subscription. Azure CLI version 2.14.0 or higher. 3 | 4 | param ( 5 | [string] $dcloc = "West Europe", 6 | [string] $rg = "aas-sample-rg", 7 | [string] $dtName = "aasrepositorydigitaltwins" 8 | ) 9 | 10 | Write-Host "`nStarting Deployment of Azure Digital Twins" $dtName "`n" 11 | 12 | # 1. Check existenc of resource group and create it if it's not existing yet 13 | $rsgExists = az group exists -n $rg 14 | if ( $rsgExists -eq 'false') { 15 | Write-Host "Resource group " $rg " doesn't exist. Creating it now." 16 | az group create -l $dcloc -n $rg 17 | } 18 | else { 19 | Write-Host "Using existing Resource Group " $rg 20 | } 21 | 22 | # 2. Create Azure Digital Twin instance 23 | $digitalTwinsExists = $(az dt list -g $rg --query "[?name=='$dtName']") | ConvertFrom-Json 24 | if ($digitalTwinsExists.Length -eq 0 ) { 25 | az dt create --dt-name $dtName -g $rg -l $dcloc --assign-identity true 26 | Write-Host "Created Azure Digital Twins Instance " $dtName 27 | 28 | # 3. Create ADT Data Owner role for current user 29 | $currAcc = $(az account show) | ConvertFrom-Json 30 | az dt role-assignment create --dt-name $dtName -g $rg --assignee $currAcc.user.name --role "Azure Digital Twins Data Owner" 31 | } 32 | else { 33 | Write-Host "Digital Twins Instance " $dtName "already exists" 34 | } -------------------------------------------------------------------------------- /scripts/azuredeployment/createAzureRedisCacheDBForRegistryServer.ps1: -------------------------------------------------------------------------------- 1 | # Create Azure Redis Cache DB for the AAS Registry service 2 | # uses the currently selected Azure subscription. Azure CLI version 2.14.0 or higher. 3 | # Will create an Azure Redis Cache DB (Basic C0). 4 | # If parameter 'appName' contains a valid Web App name in the same resource group, it will 5 | # automatically set the Web Apps config para 'AASREGISTRYCACHECONNSTRING' to the connection 6 | # string of the created Redis Cache DB. 7 | 8 | param ( 9 | [string] $dcloc = "West Europe", 10 | [string] $rg = "aas-sample-rg", 11 | [string] $cacheName = "aasregistrycache", 12 | [string] $cacheSku = "Basic", 13 | [string] $cacheVmSize = "c0", 14 | [string] $appName 15 | ) 16 | 17 | Write-Host "`nStarting Deployment of Redis Cache" $cacheName "`n" 18 | 19 | # 1. Check existenc of resource group and create it if it's not existing yet 20 | $rsgExists = az group exists -n $rg 21 | if ( $rsgExists -eq 'false') { 22 | Write-Host "Resource group " $rg " doesn't exist. Creating it now." 23 | az group create -l $dcloc -n $rg 24 | } 25 | else { 26 | Write-Host "Using existing Resource Group " $rg 27 | } 28 | 29 | # 2. Create Redis Cache if it doesn't exist yet 30 | $existingCaches=$(az redis list -g $rg --query "[?name=='$cacheName']") | ConvertFrom-Json 31 | if ($existingCaches.Length -eq 0) { 32 | Write-Host "Redis cache with name " $cacheName " doesn't exist. Creating it now" 33 | 34 | $redis=$(az redis create --location $dcloc --name $cacheName -g $rg ` 35 | --sku $cacheSku --vm-size $cacheVmSize --redis-version 6 --query [hostName,sslPort] --output tsv) 36 | 37 | # 3. Get connection string 38 | $key=$(az redis list-keys --name $cacheName -g $rg --query primaryKey --output tsv) 39 | $connString=$redis[0] + ":" + $redis[1] + ",password=" + $key + ",ssl=True,abortConnect=False" 40 | Write-Host "Redis cache connection string: " $connString 41 | 42 | # 4. Assign the connection string to an App Setting in the Web App 43 | if (-not $appName){ 44 | az webapp config appsettings set --name $appName -g $rg --settings "AASREGISTRYCACHECONNSTRING=$connString" 45 | } 46 | } 47 | else { 48 | Write-Host "Redis Cache " $cacheName " already exists" 49 | } -------------------------------------------------------------------------------- /scripts/azuredeployment/createAzureStorageForAASXFileServer.ps1: -------------------------------------------------------------------------------- 1 | # Create Azure storage account for an AASX File Server 2 | # uses the currently selected Azure subscription. Azure CLI version 2.14.0 or higher. 3 | # Will create an ADLS storage account with hierarchical namespaces 4 | 5 | param ( 6 | [string] $dcloc = "West Europe", 7 | [string] $rg = "aas-sample-rg", 8 | [string] $storageAccName = "aasxfileserverstorage", 9 | [string] $storageSku = "Standard_LRS", 10 | [string] $storageContainerName = "aasxfiles" 11 | ) 12 | 13 | Write-Host "`nStarting Deployment of Storage " $storageAccName "`n" 14 | 15 | # 1. Check existenc of resource group and create it if it's not existing yet 16 | $rsgExists = az group exists -n $rg 17 | if ( $rsgExists -eq 'false') { 18 | Write-Host "Resource group " $rg " doesn't exist. Creating it now." 19 | az group create -l $dcloc -n $rg 20 | } 21 | else { 22 | Write-Host "Using existing Resource Group " $rg 23 | } 24 | 25 | # 2. Create Azure storage account if not exists yet 26 | $storageAccExists = $(az storage account check-name --name $storageAccName) | ConvertFrom-Json 27 | if ( $storageAccExists.nameAvailable ) { 28 | Write-Host "Storage account " $storageAccName " doesn't exist. Creating it now." 29 | az storage account create -n $storageAccName -g $rg -l $dcloc --access-tier Hot --sku $storageSku --kind "StorageV2" ` 30 | --allow-blob-public-access false --allow-shared-key-access false --enable-hierarchical-namespace true 31 | } 32 | else { 33 | Write-Host " Using existing Storage Account " $storageAccName 34 | } 35 | 36 | # 3. Create container for AASX file packages 37 | $contExists = $(az storage container exists --name aasxfiles --account-name $storageAccName --auth-mode login) | ConvertFrom-Json 38 | if (-not($contExists.exists) ) { 39 | Write-Host "Container for AASX packages doesn't exist. Creating it now." 40 | az storage container create --name $storageContainerName --account-name $storageAccName --auth-mode login 41 | } 42 | else { 43 | Write-Host "Storage Container " $storageContainerName " already exists" 44 | } 45 | 46 | # 4. Assign roles to creating user 47 | $currAcc = $(az account show) | ConvertFrom-Json 48 | $storageAccId = $(az storage account show -n $storageAccName -g $rg --query id) 49 | az role assignment create --role "Storage Blob Data Owner" --assignee $currAcc.user.name --scope $storageAccId 50 | 51 | # 5. Set correct access 52 | # $oldContAcc = $(az storage fs access show --account-name $storageAccName --file-system aasxfiles --path . --auth-mode login) 53 | az storage fs access set --acl "user::rwx,group::r-x,other::r-x" --path . -f aasxfiles --account-name $storageAccName --auth-mode login 54 | -------------------------------------------------------------------------------- /scripts/azuredeployment/createWebApiAppForService.ps1: -------------------------------------------------------------------------------- 1 | # Create Azure Web Api app for AAS Services 2 | # uses the currently selected Azure subscription. Azure CLI version 2.14.0 or higher. 3 | 4 | param ( 5 | [string] $dcloc = "West Europe", 6 | [string] $rg = "aas-sample-rg", 7 | [string] $planName = "aasappserviceplan", 8 | [string] $planSku = "B1", 9 | [string] $appName = "aasapiservice" 10 | ) 11 | 12 | Write-Host "`nStarting Deployment of AASWebApi" $appName "`n" 13 | 14 | # 1. Check existenc of resource group and create it if it's not existing yet 15 | $rsgExists = az group exists -n $rg 16 | if ( $rsgExists -eq 'false') { 17 | Write-Host "Resource group " $rg " doesn't exist. Creating it now." 18 | az group create -l $dcloc -n $rg 19 | } 20 | else { 21 | Write-Host "Using existing Ressource Group" $rg 22 | } 23 | 24 | # 2. Create App service plan if it doesn't exist yet 25 | $existingPlans=$(az appservice plan list -g $rg --query "[?name=='$planName']") | ConvertFrom-Json 26 | if ($existingPlans.Length -eq 0) { 27 | Write-Host "Creating App Service Plan " $planName 28 | az appservice plan create --name $planName -g $rg --location $dcloc --is-linux --sku $planSku 29 | } 30 | else { 31 | Write-Host "Using existing App Service Plan " $planName 32 | } 33 | 34 | # 3. Create Web app 35 | $existingWebApps=$(az webapp list -g $rg --query "[?name=='$planName']") | ConvertFrom-Json 36 | if ($existingWebApps.Length -eq 0) { 37 | Write-Host "Creating Web App" $appName 38 | az webapp create -g $rg -p $planName -n $appName --runtime "DOTNET:6.0" --assign-identity 39 | # 4. Create App registration for Web app 40 | $clientId = $(az ad app create --display-name $appName --sign-in-audience 'AzureADMyOrg' --app-roles '@aasapiservicestdroles.json' --query appId -o tsv) 41 | 42 | # 5. Set Azure AD configurtion in Web app 43 | az webapp config appsettings set --name $appName -g $rg --settings "AzureAd__ClientId=$clientId" 44 | } 45 | else { 46 | Write-Host "WebApp" $appName "already exists" 47 | } 48 | # TODO Set 'kind' to "linux,api" with 'az resource update' to enable API features in portal 49 | 50 | 51 | -------------------------------------------------------------------------------- /scripts/azuredeployment/deployAzureInfrastructure.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string] $dcloc = "West Europe", 3 | [string] $rg = "aas-sample-rg", 4 | 5 | [string] $planName = "aasappserviceplan", 6 | [string] $planSku = "B1", 7 | [string] $appName = "aasapiservice", 8 | 9 | [string] $storageAccName = "aasxfileserverstorage", 10 | [string] $storageSku = "Standard_LRS", 11 | [string] $storageContainerName = "aasxfiles", 12 | 13 | [string] $dtName = "aasrepositorydigitaltwins", 14 | 15 | [string] $cacheName = "aasregistrycache", 16 | [string] $cacheSku = "Basic", 17 | [string] $cacheVmSize = "c0" 18 | ) 19 | 20 | .\createWebApiAppForService.ps1 -dcloc $dcloc -rg $rg -planName $planName -planSku $planSku -appName $appName 21 | .\createAzureStorageForAASXFileServer.ps1 -dcloc $dcloc -rg $rg -storageAccName $storageAccName -storageSku $storageSku 22 | .\createAzureDigitalTwinsInstance.ps1 -dcloc $dcloc -rg $rg -dtName $dtname 23 | .\createAzureRedisCacheDBForRegistryServer.ps1 -rg $rg -dcloc $dcloc -cacheName $cacheName -cacheSku $cacheSku -cacheVmSize $cacheVmSize -appName $appName -------------------------------------------------------------------------------- /scripts/dockerbuilds/buildRegistryACRTask.ps1: -------------------------------------------------------------------------------- 1 | az acr task create ` 2 | --registry aasapiimages ` 3 | --name buildregistryV30RC02 ` 4 | --image aas-registry-server:latest ` 5 | --context https://github.com/JMayrbaeurl/opendigitaltwins-aas-azureservices.git#V30RC02_Registry ` 6 | --file src/aas-api-webapp-registry/Dockerfile ` 7 | --git-access-token -------------------------------------------------------------------------------- /scripts/dockerbuilds/buildRegistryDockerImage.ps1: -------------------------------------------------------------------------------- 1 | # Make sure to run this script from the root folder of the solution 2 | 3 | az acr build -f .\src\aas-api-webapp-registry\Dockerfile --registry aasapiimages --image aas-registry-server:latest . -------------------------------------------------------------------------------- /src/AAS ADT SDK Tests/AAS ADT SDK Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS.ADT.Tests 6 | enable 7 | enable 8 | 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | PreserveNewest 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/AAS ADT SDK Tests/AAS ADT SDK Tests.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False -------------------------------------------------------------------------------- /src/AAS ADT SDK Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /src/AAS ADT SDK Tests/appsettings.tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "ADT_SERVICE_URL": "https://aasadtjmstaging.api.weu.digitaltwins.azure.net" 11 | } 12 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AAS ADT SDK.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS.ADT 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AAS ADT SDK.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True 4 | True -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtAssetAdministrationShellProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | using AutoMapper; 5 | 6 | namespace AAS.ADT.AutoMapper 7 | { 8 | public class AdtAssetAdministrationShellProfile : Profile 9 | { 10 | public AdtAssetAdministrationShellProfile() 11 | { 12 | CreateMap() 13 | .IncludeBase() 14 | .ForMember(d => d.AssetInformation, o => o.MapFrom( 15 | s => GetAssetInformation(s.AssetInformation.GlobalAssetId))) 16 | .ForMember(d => d.DerivedFrom,o=> o.Ignore()) 17 | .ForMember(d => d.EmbeddedDataSpecifications, o => o.Ignore()) 18 | .ForMember(d => d.Submodels, o => o.Ignore()) 19 | .ConstructUsing(x => new AssetAdministrationShell(x.Id, null, null, null, null, null, null, null, null, null, null, null)); 20 | 21 | CreateMap() 22 | .ForMember(d => d.SpecificAssetIds, o => o.Ignore()) 23 | .ForMember(d => d.DefaultThumbnail, o => o.Ignore()) 24 | .ForMember(d => d.GlobalAssetId, o => o.Ignore()) 25 | .ConstructUsing(x => new AssetInformation(AssetKind.Instance, null, null, null)); 26 | } 27 | 28 | public AssetInformation GetAssetInformation(string globalAssetId) 29 | { 30 | var specificAssetIds = new List(); 31 | 32 | 33 | var assetInformation = new AssetInformation( 34 | AssetKind.Instance, 35 | new Reference( 36 | ReferenceTypes.GlobalReference, 37 | new List() { new Key(KeyTypes.GlobalReference, globalAssetId) }),null,null 38 | ); 39 | 40 | 41 | return assetInformation; 42 | 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtBaseProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | using AutoMapper; 5 | 6 | namespace AAS.ADT.AutoMapper 7 | { 8 | public class AdtBaseProfile : Profile 9 | { 10 | public List ConvertAdtLangStringToGeneraLangString(AdtLanguageString adtLangString) 11 | { 12 | var languageStrings = new List(); 13 | 14 | if (adtLangString == null || adtLangString.LangStrings == null) 15 | { 16 | return null; 17 | } 18 | else 19 | { 20 | foreach (var langString in adtLangString.LangStrings) 21 | { 22 | languageStrings.Add(new LangString(langString.Key, langString.Value)); 23 | } 24 | 25 | return languageStrings; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtIdentifiableProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | using AutoMapper; 5 | 6 | namespace AAS.ADT.AutoMapper 7 | { 8 | public class AdtIdentifiableProfile : Profile 9 | { 10 | public AdtIdentifiableProfile() 11 | { 12 | CreateMap() 13 | .IncludeBase() 14 | .ForMember(d => d.Administration, 15 | o => o.MapFrom(s => CreateAdministrationFromAdtAdministration(s.Administration))); 16 | } 17 | 18 | public AdministrativeInformation CreateAdministrationFromAdtAdministration(AdtAdministration adtAdministration) 19 | { 20 | return new AdministrativeInformation( 21 | new List(), 22 | adtAdministration.Version, 23 | adtAdministration.Revision); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtIec61360Profile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | 5 | namespace AAS.ADT.AutoMapper 6 | { 7 | public class AdtIec61360Profile : AdtBaseProfile 8 | { 9 | public AdtIec61360Profile() 10 | { 11 | CreateMap() 12 | .ForMember(d => d.PreferredName, 13 | o => o.MapFrom(s => ConvertAdtLangStringToGeneraLangString(s.PreferredName))) 14 | .ForMember(d => d.Definition, o => o.MapFrom(s => ConvertAdtLangStringToGeneraLangString(s.Definition))) 15 | .ForMember(d => d.ShortName, o => o.MapFrom(s => ConvertAdtLangStringToGeneraLangString(s.ShortName))) 16 | .ForMember(s => s.ValueList, o => o.Ignore()) 17 | .ForMember(d => d.UnitId, o => o.MapFrom(s => s.UnitIdValue == null ? null : new Reference(ReferenceTypes.GlobalReference, new List() { new Key(KeyTypes.GlobalReference, s.UnitIdValue) }, null))).ForSourceMember(s => s.UnitIdValue, opt => opt.DoNotValidate()) 18 | .ConstructUsing(x => new DataSpecificationIec61360(ConvertAdtLangStringToGeneraLangString(x.PreferredName), null, null, null, null, null, null, null, null, null, null, null)) 19 | .DisableCtorValidation(); 20 | } 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtReferableProfile.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT.Models; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.ADT.AutoMapper 5 | { 6 | public class AdtReferableProfile : AdtBaseProfile 7 | { 8 | public AdtReferableProfile() 9 | { 10 | CreateMap() 11 | .ForMember(d => d.Description, o => o.MapFrom(s => ConvertAdtLangStringToGeneraLangString(s.Description))) 12 | .ForMember(d => d.DisplayName, o => o.MapFrom(s => ConvertAdtLangStringToGeneraLangString(s.DisplayName))) 13 | .ForMember(d => d.Extensions,o => o.Ignore()); 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtReferenceProfile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using AAS.ADT.Models; 7 | using AasCore.Aas3_0_RC02; 8 | 9 | namespace AAS.ADT.AutoMapper 10 | { 11 | public class AdtReferenceProfile : AdtBaseProfile 12 | { 13 | public AdtReferenceProfile() 14 | { 15 | CreateMap() 16 | .ForMember(d => d.Keys, o => o.MapFrom(s => mapAdtKeysToReferenceKeys(s))) 17 | .ForMember(d => d.ReferredSemanticId, o => o.Ignore()) 18 | .ConstructUsing(d => new Reference(ReferenceTypes.GlobalReference,new List(),null)); 19 | } 20 | 21 | private List mapAdtKeysToReferenceKeys(AdtReference adtReference) 22 | { 23 | var keys = new List(); 24 | var adtKeys = GetAdtKeysAsList(adtReference); 25 | foreach (var adtKey in adtKeys) 26 | { 27 | if (adtKey != null) 28 | { 29 | var keyType = new KeyTypes(); 30 | var keyTypeIsParseble = Enum.TryParse(adtKey.Type.ToString(), true, out keyType); 31 | if (keyTypeIsParseble) 32 | { 33 | keys.Add(new Key(keyType, adtKey.Value)); 34 | } 35 | } 36 | } 37 | return keys; 38 | 39 | } 40 | 41 | private List GetAdtKeysAsList(AdtReference adtReference) 42 | { 43 | return new List() 44 | { 45 | adtReference.Key1, 46 | adtReference.Key2, 47 | adtReference.Key3, 48 | adtReference.Key4, 49 | adtReference.Key5, 50 | adtReference.Key6, 51 | adtReference.Key7, 52 | adtReference.Key8, 53 | }; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtSubmodelElementProfile.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT.Models; 2 | using AasCore.Aas3_0_RC02; 3 | using AutoMapper; 4 | using File = AasCore.Aas3_0_RC02.File; 5 | 6 | namespace AAS.ADT.AutoMapper 7 | { 8 | public class AdtSubmodelElementProfile : Profile 9 | { 10 | public AdtSubmodelElementProfile() 11 | { 12 | CreateMap() 13 | .IncludeBase() 14 | .ForMember(d=> d.Kind,o => o.MapFrom(s=>s.Kind.Kind)) 15 | .ForMember(d => d.SemanticId,o=> o.Ignore()) 16 | .ForMember(d => d.Qualifiers, o => o.Ignore()) 17 | .ForMember(d => d.EmbeddedDataSpecifications, o => o.Ignore()) 18 | .ForMember(d => d.SupplementalSemanticIds, o => o.Ignore()); 19 | 20 | 21 | CreateMap() 22 | .ForMember(d => d.ValueId,o=> o.Ignore()) 23 | .IncludeBase() 24 | .ConstructUsing(x => new Property(DataTypeDefXsd.Boolean,null,null,null,null, null, null, null, null, null, null, null, null,null)); 25 | 26 | CreateMap() 27 | .IncludeBase() 28 | .ConstructUsing(x => new File("FileType", null, null, null, null, null, null, null, null, null, null, null, null)); 29 | 30 | CreateMap() 31 | .IncludeBase() 32 | .ForMember(d => d.Value, o => o.Ignore()) 33 | .ConstructUsing(x => new SubmodelElementCollection(null, null, null, null, null, null, null, null, null, null, null, null)); 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/AutoMapper/AdtSubmodelProfile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | using AutoMapper; 5 | 6 | namespace AAS.ADT.AutoMapper 7 | { 8 | public class AdtSubmodelProfile : Profile 9 | { 10 | public AdtSubmodelProfile() 11 | { 12 | CreateMap() 13 | .IncludeBase() 14 | .ForMember(d => d.Kind, o => o.MapFrom(s => s.Kind.Kind)) 15 | .ForMember(d => d.SemanticId, o => o.Ignore()) 16 | .ForMember(d => d.Qualifiers, o => o.Ignore()) 17 | .ForMember(d => d.SupplementalSemanticIds, o => o.Ignore()) 18 | .ForMember(d => d.EmbeddedDataSpecifications, o => o.Ignore()) 19 | .ForMember(d => d.SubmodelElements, o => o.Ignore()) 20 | .ConstructUsing(x => new Submodel(x.Id, null, null, null, null, null, null, null, null, null, null, null,null,null)); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/AasWriteAssetAdministrationShell.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Azure.DigitalTwins.Core; 3 | using System.Threading.Tasks; 4 | using AasCore.Aas3_0_RC02; 5 | using Microsoft.Extensions.Logging; 6 | 7 | namespace AAS.ADT 8 | { 9 | public class AasWriteAssetAdministrationShell : IAasWriteAssetAdministrationShell 10 | { 11 | private readonly ILogger _logger; 12 | private readonly IAdtTwinFactory _modelFactory; 13 | private readonly IAasWriteConnector _aasWriteConnector; 14 | private readonly IAasWriteBase _writeBase; 15 | 16 | public AasWriteAssetAdministrationShell(ILogger logger, IAdtTwinFactory modelFactory, 17 | IAasWriteConnector aasWriteConnector, IAasWriteBase writeBase) 18 | { 19 | _logger = logger; 20 | _modelFactory = modelFactory; 21 | _aasWriteConnector = aasWriteConnector; 22 | _writeBase = writeBase; 23 | } 24 | 25 | public async Task CreateShell(AssetAdministrationShell shell) 26 | { 27 | if (shell == null) 28 | { 29 | return null; 30 | } 31 | 32 | _logger.LogInformation($"Now importing Administration shell '{shell.IdShort}' into ADT instance"); 33 | 34 | var twin = _modelFactory.GetTwin(shell); 35 | await _aasWriteConnector.DoCreateOrReplaceDigitalTwinAsync(twin); 36 | var tasks = new List() 37 | { 38 | _writeBase.AddHasDataSpecification(twin.Id, shell.EmbeddedDataSpecifications), 39 | CreateAssetInformation(shell, twin.Id) 40 | }; 41 | 42 | await Task.WhenAll(tasks); 43 | 44 | 45 | return twin.Id; 46 | } 47 | 48 | public async Task CreateSubmodelReference(string shellTwinId, string submodelTwinId) 49 | { 50 | await _aasWriteConnector.DoCreateOrReplaceRelationshipAsync(shellTwinId, "submodel", submodelTwinId); 51 | } 52 | 53 | private async Task CreateAssetInformation(AssetAdministrationShell shell, string shellTwinId) 54 | { 55 | var assetInfoTwinData = _modelFactory.GetTwin(shell.AssetInformation); 56 | await _aasWriteConnector.DoCreateOrReplaceDigitalTwinAsync(assetInfoTwinData); 57 | await _aasWriteConnector.DoCreateOrReplaceRelationshipAsync(shellTwinId, "assetInformation", 58 | assetInfoTwinData.Id); 59 | } 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IADTAASRepo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using AasCore.Aas3_0_RC02; 4 | 5 | namespace AAS.ADT 6 | { 7 | // Necessary for RelationshipElements 8 | public interface IAASRepo 9 | { 10 | public Task FindTwinForReference(Reference reference); 11 | 12 | public Task> FindLinkedReferences(); 13 | 14 | public Task> FindReferenceElements(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasDeleteAdt.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | 4 | namespace AAS.ADT; 5 | 6 | public interface IAasDeleteAdt 7 | { 8 | public Task DeleteTwin(string twinId); 9 | public Task DeleteRelationship(string sourceTwinId, string targetTwinId, string relationshipName); 10 | 11 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasUpdateAdt.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.ADT; 5 | 6 | public interface IAasUpdateAdt 7 | { 8 | Task UpdateFullSubmodel(string submodelTwinId, Submodel submodel); 9 | Task UpdateFullShell(string shellTwinId, AssetAdministrationShell shell); 10 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasWriteAssetAdministrationShell.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.ADT; 5 | 6 | public interface IAasWriteAssetAdministrationShell 7 | { 8 | Task CreateShell(AssetAdministrationShell shell); 9 | Task CreateSubmodelReference(string shellTwinId, string submodelTwinId); 10 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasWriteBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using AasCore.Aas3_0_RC02; 4 | 5 | namespace AAS.ADT; 6 | 7 | public interface IAasWriteBase 8 | { 9 | Task AddReference(string sourceTwinId, Reference reference, string relationshipName); 10 | 11 | Task AddHasDataSpecification(string sourceTwinId, 12 | List embeddedDataSpecifications); 13 | 14 | Task AddQualifiableRelations(string sourceTwinId, List qualifiers); 15 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasWriteConnectorForAdtCommunication.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Azure; 4 | using Azure.DigitalTwins.Core; 5 | 6 | namespace AAS.ADT; 7 | 8 | public interface IAasWriteConnector 9 | { 10 | Task DoCreateOrReplaceDigitalTwinAsync(BasicDigitalTwin twinData); 11 | 12 | Task DoCreateOrReplaceRelationshipAsync(string sourceId, 13 | string relName, string targetId); 14 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasWriteSubmodel.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.ADT; 5 | 6 | public interface IAasWriteSubmodel 7 | { 8 | Task CreateSubmodel(Submodel submodel); 9 | Task CreateSubmodelElementForSubmodel(ISubmodelElement submodelElement, string submodelTwinId); 10 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAasWriteSubmodelElements.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.ADT; 5 | 6 | public interface IAasWriteSubmodelElements 7 | { 8 | Task CreateSubmodelElement(ISubmodelElement submodelElement); 9 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Connectors/IAdtTwinFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AasCore.Aas3_0_RC02; 3 | using Azure.DigitalTwins.Core; 4 | 5 | namespace AAS.ADT; 6 | 7 | public interface IAdtTwinFactory 8 | { 9 | public BasicDigitalTwin GetTwin(ISubmodelElement submodelElement); 10 | public BasicDigitalTwin GetTwin(Reference reference); 11 | public BasicDigitalTwin GetTwin(IDataSpecificationContent content); 12 | public BasicDigitalTwin GetTwin(Qualifier qualifiers); 13 | public BasicDigitalTwin GetTwin(Submodel submodel); 14 | public BasicDigitalTwin GetTwin(AssetAdministrationShell shell); 15 | public BasicDigitalTwin GetTwin(AssetInformation assetInformation); 16 | public BasicDigitalTwin GetTwin(EmbeddedDataSpecification dataSpecification); 17 | 18 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Exceptions/ImportException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AAS.ADT 4 | { 5 | public class ImportException : Exception 6 | { 7 | public ImportException() 8 | { 9 | } 10 | 11 | public ImportException(string message) : base(message) 12 | { 13 | } 14 | 15 | public ImportException(string message, Exception innerException) : base(message, innerException) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtAas.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using Azure.DigitalTwins.Core; 3 | 4 | namespace AAS.ADT.Models 5 | { 6 | public class AdtAas : AdtIdentifiable 7 | { 8 | [JsonPropertyName("assetInformationShort")] 9 | public AdtAssetInformationShort AssetInformation { get; set; } 10 | } 11 | 12 | public class AdtAssetInformationShort 13 | { 14 | [JsonPropertyName("assetKind")] 15 | public string? AssetKind { get; set; } 16 | 17 | [JsonPropertyName("globalAssetId")] 18 | public string? GlobalAssetId { get; set; } 19 | 20 | [JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinMetadata)] 21 | public DigitalTwinMetadata Metadata { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtAdministration.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using Azure.DigitalTwins.Core; 3 | 4 | namespace AAS.ADT.Models; 5 | 6 | public class AdtAdministration : AdtBase 7 | { 8 | [JsonPropertyName("revision")] 9 | public string? Revision { get; set; } 10 | 11 | [JsonPropertyName("version")] 12 | public string? Version { get; set; } 13 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtAssetInformation.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtAssetInformation : AdtBase 6 | { 7 | 8 | [JsonPropertyName("globalAssetIdValue")] 9 | public string? GlobalAssetId { get; set; } 10 | 11 | [JsonPropertyName("specificAssetIdValues")] 12 | public string? SpecificAssetId { get; set; } 13 | 14 | [JsonPropertyName("assetKind")] 15 | public AdtAssetKind? AssetKind { get; set; } 16 | } 17 | 18 | public class AdtAssetKind 19 | { 20 | [JsonPropertyName("assetKind")] 21 | public string? AssetKind { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtBase.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using Azure.DigitalTwins.Core; 3 | 4 | namespace AAS.ADT.Models 5 | { 6 | public class AdtBase 7 | { 8 | [JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinId)] 9 | public string dtId { get; set; } 10 | 11 | [JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinMetadata)] 12 | public DigitalTwinMetadata Metadata { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtConceptDescription.cs: -------------------------------------------------------------------------------- 1 | namespace AAS.ADT.Models 2 | { 3 | public class AdtConceptDescription : AdtIdentifiable 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtDataSpecification.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtDataSpecification : AdtBase 6 | { 7 | [JsonPropertyName("administration")] 8 | public AdtAdministration Administration { get; set; } 9 | 10 | [JsonPropertyName("id")] 11 | public string Id { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public AdtLanguageString Description { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtDataSpecificationContent.cs: -------------------------------------------------------------------------------- 1 | namespace AAS.ADT.Models 2 | { 3 | public class AdtDataSpecificationContent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtDataSpecificationIEC61360.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtDataSpecificationIEC61360 : AdtDataSpecificationContent 6 | { 7 | [JsonPropertyName("definition")] 8 | public AdtLanguageString Definition { get; set; } 9 | 10 | [JsonPropertyName("preferredName")] 11 | public AdtLanguageString PreferredName { get; set; } 12 | 13 | [JsonPropertyName("shortName")] 14 | public AdtLanguageString ShortName { get; set; } 15 | 16 | [JsonPropertyName("dataType")] 17 | public string? DataType { get; set; } 18 | 19 | [JsonPropertyName("levelType")] 20 | public string? LevelType { get; set; } 21 | 22 | [JsonPropertyName("sourceOfDefinition")] 23 | public string? SourceOfDefinition { get; set; } 24 | 25 | [JsonPropertyName("symbol")] 26 | public string? Symbol { get; set; } 27 | 28 | [JsonPropertyName("unit")] 29 | public string? Unit { get; set; } 30 | 31 | [JsonPropertyName("unitIdValue")] 32 | public string? UnitIdValue { get; set; } 33 | 34 | [JsonPropertyName("value")] 35 | public string? Value { get; set; } 36 | 37 | [JsonPropertyName("valueFormat")] 38 | public string? ValueFormat { get; set; } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtFile.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtFile : AdtSubmodelElement 6 | { 7 | [JsonPropertyName("value")] 8 | public string? Value { get; set; } 9 | 10 | [JsonPropertyName("contentType")] 11 | public string? ContentType { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtHasKind.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models; 4 | 5 | public class AdtHasKind 6 | { 7 | [JsonPropertyName("kind")] 8 | public string? Kind { get; set; } 9 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtIdentifiable.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models; 4 | 5 | public class AdtIdentifiable : AdtReferable 6 | { 7 | [JsonPropertyName("id")] 8 | public string? Id { get; set; } 9 | 10 | [JsonPropertyName("administration")] 11 | public AdtAdministration? Administration { get; set; } 12 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtKey.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtKey 6 | { 7 | [JsonPropertyName("type")] 8 | public string? Type { get; set; } 9 | [JsonPropertyName("value")] 10 | public string? Value { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtLanguageString.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text.Json.Serialization; 3 | using Azure.DigitalTwins.Core; 4 | 5 | namespace AAS.ADT.Models; 6 | 7 | public class AdtLanguageString 8 | { 9 | [JsonPropertyName("langString")] 10 | public Dictionary? LangStrings { get; set; } 11 | 12 | [JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinMetadata)] 13 | public DigitalTwinMetadata Metadata { get; set; } 14 | } -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtProperty.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtProperty : AdtSubmodelElement 6 | { 7 | 8 | 9 | [JsonPropertyName("value")] 10 | public string? Value { get; set; } 11 | 12 | [JsonPropertyName("valueType")] 13 | public string? ValueType { get; set; } 14 | 15 | 16 | 17 | 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtReferable.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtReferable : AdtBase 6 | { 7 | [JsonPropertyName("category")] 8 | public string? Category { get; set; } 9 | 10 | [JsonPropertyName("description")] 11 | public AdtLanguageString? Description { get; set; } 12 | 13 | [JsonPropertyName("displayName")] 14 | public AdtLanguageString? DisplayName { get; set; } 15 | 16 | [JsonPropertyName("checksum")] 17 | public string? Checksum { get; set; } 18 | 19 | [JsonPropertyName("idShort")] 20 | public string? IdShort { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtReference.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtReference : AdtBase 6 | { 7 | 8 | [JsonPropertyName("key1")] 9 | public AdtKey? Key1 { get; set; } 10 | 11 | [JsonPropertyName("key2")] 12 | public AdtKey? Key2 { get; set; } 13 | 14 | [JsonPropertyName("key3")] 15 | public AdtKey? Key3 { get; set; } 16 | 17 | [JsonPropertyName("key4")] 18 | public AdtKey? Key4 { get; set; } 19 | 20 | [JsonPropertyName("key5")] 21 | public AdtKey? Key5 { get; set; } 22 | 23 | [JsonPropertyName("key6")] 24 | public AdtKey? Key6 { get; set; } 25 | 26 | [JsonPropertyName("key7")] 27 | public AdtKey? Key7 { get; set; } 28 | 29 | [JsonPropertyName("key8")] 30 | public AdtKey? Key8 { get; set; } 31 | 32 | [JsonPropertyName("type")] 33 | public string? Type { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtRelationship.cs: -------------------------------------------------------------------------------- 1 | namespace AAS.ADT.Models 2 | { 3 | internal class AdtRelationship 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtSubmodel.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtSubmodel : AdtIdentifiable 6 | { 7 | [JsonPropertyName("kind")] 8 | public AdtHasKind Kind { get; set; } 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtSubmodelElement.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtSubmodelElement : AdtReferable 6 | { 7 | [JsonPropertyName("kind")] 8 | public AdtHasKind? Kind { get; set; } 9 | 10 | [JsonPropertyName("semanticIdValue")] 11 | public string? SemanticIdValue { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AAS ADT SDK/Models/AdtSubmodelElementCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace AAS.ADT.Models 4 | { 5 | public class AdtSubmodelElementCollection : AdtSubmodelElement 6 | { 7 | public List submodelElements = new List(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/aas-aasxfile-service-tests/AAS AASX File Service Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS_AASX_File_Service_Tests 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | true 18 | PreserveNewest 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | all 34 | runtime; build; native; contentfiles; analyzers; buildtransitive 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Always 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/aas-aasxfile-service-tests/Resources/01_Festo.aasx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/src/aas-aasxfile-service-tests/Resources/01_Festo.aasx -------------------------------------------------------------------------------- /src/aas-aasxfile-service-tests/appsettings.tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "AASX_FILESERVICE_CONTAINERNAME": "aasxfiles", 11 | "AASX_FILESERVICE_BLOBSTORAGEURL": "https://aasxstoragejm.blob.core.windows.net/" 12 | } 13 | -------------------------------------------------------------------------------- /src/aas-aasxfile-service/AAS AASX File Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS_AASX_File_Service 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/aas-aasxfile-service/AASAASXFile.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models.Interfaces; 2 | using AAS.API.Services; 3 | using System; 4 | 5 | namespace AAS.API.AASXFile 6 | { 7 | public interface AASAASXFile : AASXFileServer 8 | { 9 | } 10 | public class AASXFileServiceException : AASServiceException 11 | { 12 | // 13 | // Summary: 14 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 15 | // error message. 16 | // 17 | // Parameters: 18 | // message: 19 | // The message that describes the error. 20 | public AASXFileServiceException(string message) : base(message) 21 | { 22 | } 23 | // 24 | // Summary: 25 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 26 | // error message, HTTP status code and a reference to the inner exception that is 27 | // the cause of this exception. 28 | // 29 | // Parameters: 30 | // message: 31 | // The error message that explains the reason for the exception. 32 | // 33 | // innerException: 34 | // The exception that is the cause of the current exception, or a null reference 35 | // (Nothing in Visual Basic) if no inner exception is specified. 36 | public AASXFileServiceException(string message, Exception? innerException) : base(message, innerException) 37 | { 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/aas-api-models/AAS API Models.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS.API.Models 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/AAS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace AAS.API.Interfaces 6 | { 7 | public interface AAS 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/AASXFileServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | 6 | namespace AAS.API.Models.Interfaces 7 | { 8 | public interface AASXFileServer 9 | { 10 | /// 11 | /// Returns a specific AASX package from the server 12 | /// 13 | /// The package Id (BASE64-URL-encoded) 14 | public Task GetAASXByPackageId(string packageId); 15 | 16 | /// 17 | /// Returns a list of available AASX packages at the server 18 | /// 19 | /// The Asset Administration Shell’s unique id (BASE64-URL-encoded) 20 | public Task> GetAllAASXPackageIds(string aasId); 21 | 22 | /// 23 | /// Deletes a specific AASX package from the server 24 | /// 25 | /// The Package Id (BASE64-URL-encoded) 26 | public Task DeleteAASXByPackageId(string packageId); 27 | 28 | /// 29 | /// Stores the AASX package at the server 30 | /// 31 | public Task StoreAASXPackage(List aasIds, byte[] file, string fileName); 32 | 33 | /// 34 | /// Updates the AASX package at the server 35 | /// 36 | public Task UpdateAASXPackage(string packageId, List aasIds, byte[] file, string fileName); 37 | } 38 | 39 | public class PackageFile 40 | { 41 | private string filename; 42 | 43 | public string Filename 44 | { 45 | get { return filename; } 46 | set { filename = value; } 47 | } 48 | private byte[] contents; 49 | 50 | public byte[] Contents 51 | { 52 | get { return contents; } 53 | set { contents = value; } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/BasicDiscovery.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace AAS.API.Interfaces 8 | { 9 | public interface BasicDiscovery 10 | { 11 | 12 | public Task> GetAllAssetAdministrationShellIdsByAssetLink(List assetIds); 13 | 14 | public Task> GetAllAssetLinksById(string aasIdentifier); 15 | 16 | public Task> CreateAllAssetLinksById(string aasIdentifier, List assetIds); 17 | 18 | public Task> DeleteAllAssetLinksById(string aasIdentifier); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/Registry.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace AAS.API.Interfaces 6 | { 7 | public interface Registry 8 | { 9 | public Task> GetAllAssetAdministrationShellDescriptors(int maxItems = 100); 10 | 11 | public Task GetAssetAdministrationShellDescriptorById(string aasIdentifier); 12 | 13 | public Task CreateAssetAdministrationShellDescriptor(AssetAdministrationShellDescriptor aasDesc); 14 | 15 | public Task UpdateAssetAdministrationShellDescriptorById(AssetAdministrationShellDescriptor aasDesc); 16 | 17 | public Task DeleteAssetAdministrationShellDescriptorById(string aasIdentifier); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/ShellRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using AasCore.Aas3_0_RC02; 6 | 7 | 8 | namespace AAS.API.Interfaces 9 | { 10 | public interface ShellRepository 11 | { 12 | public Task> GetAllAdministrationShells(); 13 | 14 | public Task> GetAllAssetAdministrationShellsByAssetId(List assetIds); 15 | 16 | public Task> GetAllAssetAdministrationShellsByIdShort(string withIdShort); 17 | 18 | public Task GetAssetAdministrationShellWithId(string aasIdentifier); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/SubmodelRegistry.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace AAS.API.Interfaces 6 | { 7 | public interface SubmodelRegistry 8 | { 9 | public Task> GetAllSubmodelDescriptors(int maxItems = 100); 10 | 11 | public Task GetSubmodelDescriptorById(string submodelIdentifier); 12 | 13 | public Task CreateSubmodelDescriptor(SubmodelDescriptor submodelDescriptor); 14 | 15 | public Task UpdateSubmodelDescriptorById(SubmodelDescriptor submodelDescriptor); 16 | 17 | public Task DeleteSubmodelDescriptorById(string idsubmodelIdentifier); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-models/Interfaces/Submodels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace AAS.API.Interfaces 6 | { 7 | public interface Submodels 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/aas-api-models/Models/AssetKind.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * DotAAS Part 2 | HTTP/REST | Entire API Collection 3 | * 4 | * The entire API collection as part of Details of the Asset Administration Shell Part 2 5 | * 6 | * OpenAPI spec version: V1.0RC03 7 | * 8 | * Generated by: https://github.com/swagger-api/swagger-codegen.git 9 | */ 10 | using System; 11 | using System.Linq; 12 | using System.IO; 13 | using System.Text; 14 | using System.Collections; 15 | using System.Collections.Generic; 16 | using System.Collections.ObjectModel; 17 | using System.ComponentModel.DataAnnotations; 18 | using System.Runtime.Serialization; 19 | using Newtonsoft.Json; 20 | 21 | namespace AAS.API.Models 22 | { 23 | /// 24 | /// Gets or Sets AssetKind 25 | /// 26 | [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] 27 | public enum AssetKind 28 | { 29 | /// 30 | /// Enum InstanceEnum for Instance 31 | /// 32 | [EnumMember(Value = "Instance")] 33 | InstanceEnum = 0, 34 | /// 35 | /// Enum TypeEnum for Type 36 | /// 37 | [EnumMember(Value = "Type")] 38 | TypeEnum = 1 } 39 | } 40 | -------------------------------------------------------------------------------- /src/aas-api-models/Models/ExecutionState.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * DotAAS Part 2 | HTTP/REST | Entire API Collection 3 | * 4 | * The entire API collection as part of Details of the Asset Administration Shell Part 2 5 | * 6 | * OpenAPI spec version: V1.0RC03 7 | * 8 | * Generated by: https://github.com/swagger-api/swagger-codegen.git 9 | */ 10 | using System; 11 | using System.Linq; 12 | using System.IO; 13 | using System.Text; 14 | using System.Collections; 15 | using System.Collections.Generic; 16 | using System.Collections.ObjectModel; 17 | using System.ComponentModel.DataAnnotations; 18 | using System.Runtime.Serialization; 19 | using Newtonsoft.Json; 20 | 21 | namespace AAS.API.Models 22 | { 23 | /// 24 | /// Gets or Sets ExecutionState 25 | /// 26 | [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] 27 | public enum ExecutionState 28 | { 29 | /// 30 | /// Enum InitiatedEnum for Initiated 31 | /// 32 | [EnumMember(Value = "Initiated")] 33 | InitiatedEnum = 0, 34 | /// 35 | /// Enum RunningEnum for Running 36 | /// 37 | [EnumMember(Value = "Running")] 38 | RunningEnum = 1, 39 | /// 40 | /// Enum CompletedEnum for Completed 41 | /// 42 | [EnumMember(Value = "Completed")] 43 | CompletedEnum = 2, 44 | /// 45 | /// Enum CanceledEnum for Canceled 46 | /// 47 | [EnumMember(Value = "Canceled")] 48 | CanceledEnum = 3, 49 | /// 50 | /// Enum FailedEnum for Failed 51 | /// 52 | [EnumMember(Value = "Failed")] 53 | FailedEnum = 4, 54 | /// 55 | /// Enum TimeoutEnum for Timeout 56 | /// 57 | [EnumMember(Value = "Timeout")] 58 | TimeoutEnum = 5 } 59 | } 60 | -------------------------------------------------------------------------------- /src/aas-api-models/Models/ModelingKind.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * DotAAS Part 2 | HTTP/REST | Entire API Collection 3 | * 4 | * The entire API collection as part of Details of the Asset Administration Shell Part 2 5 | * 6 | * OpenAPI spec version: V1.0RC03 7 | * 8 | * Generated by: https://github.com/swagger-api/swagger-codegen.git 9 | */ 10 | using System; 11 | using System.Linq; 12 | using System.IO; 13 | using System.Text; 14 | using System.Collections; 15 | using System.Collections.Generic; 16 | using System.Collections.ObjectModel; 17 | using System.ComponentModel.DataAnnotations; 18 | using System.Runtime.Serialization; 19 | using Newtonsoft.Json; 20 | 21 | namespace AAS.API.Models 22 | { 23 | /// 24 | /// Gets or Sets ModelingKind 25 | /// 26 | [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] 27 | public enum ModelingKind 28 | { 29 | /// 30 | /// Enum InstanceEnum for Instance 31 | /// 32 | [EnumMember(Value = "Instance")] 33 | InstanceEnum = 0, 34 | /// 35 | /// Enum TemplateEnum for Template 36 | /// 37 | [EnumMember(Value = "Template")] 38 | TemplateEnum = 1 } 39 | } 40 | -------------------------------------------------------------------------------- /src/aas-api-models/Models/QualifierKind.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * DotAAS Part 2 | HTTP/REST | Entire API Collection 3 | * 4 | * The entire API collection as part of Details of the Asset Administration Shell Part 2 5 | * 6 | * OpenAPI spec version: V1.0RC03 7 | * 8 | * Generated by: https://github.com/swagger-api/swagger-codegen.git 9 | */ 10 | using System; 11 | using System.Linq; 12 | using System.IO; 13 | using System.Text; 14 | using System.Collections; 15 | using System.Collections.Generic; 16 | using System.Collections.ObjectModel; 17 | using System.ComponentModel.DataAnnotations; 18 | using System.Runtime.Serialization; 19 | using Newtonsoft.Json; 20 | 21 | namespace AAS.API.Models 22 | { 23 | /// 24 | /// Gets or Sets QualifierKind 25 | /// 26 | [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] 27 | public enum QualifierKind 28 | { 29 | /// 30 | /// Enum ConceptQualifierEnum for ConceptQualifier 31 | /// 32 | [EnumMember(Value = "ConceptQualifier")] 33 | ConceptQualifierEnum = 0, 34 | /// 35 | /// Enum TemplateQualifierEnum for TemplateQualifier 36 | /// 37 | [EnumMember(Value = "TemplateQualifier")] 38 | TemplateQualifierEnum = 1, 39 | /// 40 | /// Enum ValueQualifierEnum for ValueQualifier 41 | /// 42 | [EnumMember(Value = "ValueQualifier")] 43 | ValueQualifierEnum = 2 } 44 | } 45 | -------------------------------------------------------------------------------- /src/aas-api-models/Models/ReferenceTypes.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * DotAAS Part 2 | HTTP/REST | Entire API Collection 3 | * 4 | * The entire API collection as part of Details of the Asset Administration Shell Part 2 5 | * 6 | * OpenAPI spec version: V1.0RC03 7 | * 8 | * Generated by: https://github.com/swagger-api/swagger-codegen.git 9 | */ 10 | using System; 11 | using System.Linq; 12 | using System.IO; 13 | using System.Text; 14 | using System.Collections; 15 | using System.Collections.Generic; 16 | using System.Collections.ObjectModel; 17 | using System.ComponentModel.DataAnnotations; 18 | using System.Runtime.Serialization; 19 | using Newtonsoft.Json; 20 | 21 | namespace AAS.API.Models 22 | { 23 | /// 24 | /// Gets or Sets ReferenceTypes 25 | /// 26 | [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] 27 | public enum ReferenceTypes 28 | { 29 | /// 30 | /// Enum GlobalReferenceEnum for GlobalReference 31 | /// 32 | [EnumMember(Value = "GlobalReference")] 33 | GlobalReferenceEnum = 0, 34 | /// 35 | /// Enum ModelReferenceEnum for ModelReference 36 | /// 37 | [EnumMember(Value = "ModelReference")] 38 | ModelReferenceEnum = 1 } 39 | } 40 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt-tests/ADTAASRepoStandardTests.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT; 2 | using AAS.API.Services.ADT; 3 | using AasCore.Aas3_0_RC02; 4 | using AutoMapper; 5 | using Microsoft.Extensions.Logging; 6 | 7 | namespace AAS.API.Repository.Adt.Tests 8 | { 9 | [TestClass] 10 | public class ADTAASRepoStandardTests 11 | { 12 | [TestMethod] 13 | public void TestConvertStringListToQueryArrayString() 14 | { 15 | List values = new List() { "First", "Second", "Third" }; 16 | string queryString = AbstractADTAASService.ConvertStringListToQueryArrayString(values); 17 | Assert.AreEqual(queryString, "['First','Second','Third']"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt-tests/AasRepositoryAdtTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | AAS.API.Repository.Adt.Tests 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt-tests/AasRepositoryAdtTests.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True -------------------------------------------------------------------------------- /src/aas-api-repository-adt-tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /src/aas-api-repository-adt-tests/appsettings.tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "ADT_SERVICE_URL": "https://aasadtjmstaging.api.weu.digitaltwins.azure.net" 11 | } 12 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt/AasRepositoryAdt.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | AAS.API.Repository.Adt 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt/AasRepositoryAdt.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True 4 | True 5 | True 6 | True -------------------------------------------------------------------------------- /src/aas-api-repository-adt/Common/AdtDataTransferObjects.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Nodes; 2 | using AAS.ADT.Models; 3 | using Azure.DigitalTwins.Core; 4 | 5 | namespace AAS.API.Repository.Adt 6 | { 7 | 8 | public class DefinitionsAndSemantics 9 | { 10 | public Dictionary References = new(); 11 | 12 | public Dictionary Iec61360s = new(); 13 | 14 | public Dictionary ConceptDescriptions = new(); 15 | 16 | public Dictionary> Relationships = new(); 17 | } 18 | 19 | public class AdtGeneralAasInformation where T : AdtBase, new() 20 | { 21 | public AdtGeneralAasInformation() 22 | { 23 | rootElement = new T(); 24 | } 25 | public T rootElement { get; set; } 26 | } 27 | 28 | public class AdtSubmodelElements 29 | { 30 | public List> smeCollections = new(); 31 | public List properties = new(); 32 | public List files = new(); 33 | } 34 | 35 | 36 | public class AdtSubmodelAndSmcInformation where T : AdtBase, new() 37 | { 38 | public AdtSubmodelAndSmcInformation() 39 | { 40 | RootElement = new T(); 41 | } 42 | 43 | public T RootElement { get; set; } 44 | 45 | public DefinitionsAndSemantics DefinitionsAndSemantics = new(); 46 | public AdtSubmodelElements AdtSubmodelElements = new(); 47 | } 48 | 49 | public class AdtAssetAdministrationShellInformation : AdtGeneralAasInformation 50 | { 51 | public List Submodels = new(); 52 | public AdtAas? DerivedFrom = null; 53 | public AdtAssetInformation? AssetInformation = null; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt/Connectors/IAdtAasConnector.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT.Models; 2 | 3 | namespace AAS.API.Repository.Adt; 4 | 5 | public interface IAdtAasConnector 6 | { 7 | List GetAllAasIds(); 8 | AdtAas GetAdtAasForAasWithId(string aasId); 9 | AdtAssetAdministrationShellInformation GetAllInformationForAasWithId(string aasId); 10 | Task> GetAllSubmodelTwinIds(); 11 | string GetTwinIdForElementWithId(string Id); 12 | } -------------------------------------------------------------------------------- /src/aas-api-repository-adt/Connectors/IAdtSubmodelConnector.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Nodes; 2 | using AAS.ADT.Models; 3 | using AasCore.Aas3_0_RC02; 4 | 5 | namespace AAS.API.Repository.Adt; 6 | 7 | public interface IAdtSubmodelConnector 8 | { 9 | Task> GetAllInformationForSubmodelWithTwinId(string twinId); 10 | } -------------------------------------------------------------------------------- /src/aas-api-repository-adt/Exceptions/AasAdtExceptions.cs: -------------------------------------------------------------------------------- 1 | namespace AAS.API.Repository.Adt 2 | { 3 | class AdtException : Exception 4 | { 5 | public AdtException(string message) : base(message) 6 | { 7 | } 8 | 9 | public AdtException(string message, Exception? innerException) : base(message, innerException) 10 | { 11 | } 12 | } 13 | 14 | public class NoSemanticIdFound : Exception 15 | { 16 | public NoSemanticIdFound(string message) : base(message) 17 | { 18 | } 19 | 20 | public NoSemanticIdFound(string message, Exception? innerException) : base(message, innerException) 21 | { 22 | } 23 | 24 | } 25 | public class AdtModelNotSupported : Exception 26 | { 27 | public AdtModelNotSupported(string message) : base(message) 28 | { 29 | } 30 | 31 | public AdtModelNotSupported(string message, Exception? innerException) : base(message, innerException) 32 | { 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt/ModelFactories/AdtSubmodelModelFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using AAS.ADT.Models; 5 | using AasCore.Aas3_0_RC02; 6 | using AutoMapper; 7 | 8 | namespace AAS.API.Repository.Adt 9 | { 10 | public class AdtSubmodelModelFactory : IAdtSubmodelModelFactory 11 | { 12 | private readonly IAdtSubmodelElementFactory _adtSubmodelElementFactory; 13 | private readonly IAdtDefinitionsAndSemanticsModelFactory _definitionsAndSemanticsFactory; 14 | private readonly IMapper _mapper; 15 | 16 | public AdtSubmodelModelFactory(IAdtDefinitionsAndSemanticsModelFactory definitionsAndSemanticsFactory, 17 | IAdtSubmodelElementFactory adtSubmodelElementFactory, IMapper mapper) 18 | { 19 | _adtSubmodelElementFactory = adtSubmodelElementFactory; 20 | _mapper = mapper?? 21 | throw new ArgumentNullException(nameof(mapper)); 22 | _definitionsAndSemanticsFactory = definitionsAndSemanticsFactory; 23 | } 24 | 25 | 26 | public Submodel GetSubmodel(AdtSubmodelAndSmcInformation information) 27 | { 28 | var submodelTwinId = information.RootElement.dtId; 29 | 30 | var submodel = _mapper.Map(information.RootElement); 31 | 32 | submodel.SemanticId = 33 | _definitionsAndSemanticsFactory.GetSemanticIdForTwin(submodelTwinId, 34 | information.DefinitionsAndSemantics); 35 | 36 | submodel.EmbeddedDataSpecifications = _definitionsAndSemanticsFactory 37 | .GetEmbeddedDataSpecificationsForTwin(submodelTwinId, 38 | information.DefinitionsAndSemantics); 39 | 40 | submodel.SupplementalSemanticIds = _definitionsAndSemanticsFactory.GetSupplementalSemanticIdsForTwin( 41 | submodelTwinId, information.DefinitionsAndSemantics); 42 | 43 | submodel.SubmodelElements = _adtSubmodelElementFactory.GetSubmodelElements( 44 | information.AdtSubmodelElements,information.DefinitionsAndSemantics); 45 | 46 | return submodel; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/aas-api-repository-adt/ModelFactories/IAdtDefinitionsAndSemanticsModelFactory.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT.Models; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.API.Repository.Adt; 5 | 6 | public interface IAdtDefinitionsAndSemanticsModelFactory 7 | { 8 | public Reference? GetSemanticId(AdtReference adtReference); 9 | public Reference? GetSemanticIdForTwin(string twinId, DefinitionsAndSemantics definitionsAndSemantics); 10 | List? GetSupplementalSemanticIdsForTwin(string twinId, DefinitionsAndSemantics definitionsAndSemantics); 11 | List? GetEmbeddedDataSpecificationsForTwin(string dtId, DefinitionsAndSemantics definitionsAndSemantics); 12 | } -------------------------------------------------------------------------------- /src/aas-api-repository-adt/ModelFactories/IAdtSubmodelElementFactory.cs: -------------------------------------------------------------------------------- 1 | using AasCore.Aas3_0_RC02; 2 | 3 | namespace AAS.API.Repository.Adt; 4 | 5 | public interface IAdtSubmodelElementFactory 6 | { 7 | List GetSubmodelElements( 8 | AdtSubmodelElements adtSubmodelElements, DefinitionsAndSemantics definitionsAndSemantics); 9 | } -------------------------------------------------------------------------------- /src/aas-api-repository-adt/ModelFactories/IAdtSubmodelModelFactory.cs: -------------------------------------------------------------------------------- 1 | using AAS.ADT.Models; 2 | using AasCore.Aas3_0_RC02; 3 | 4 | namespace AAS.API.Repository.Adt; 5 | 6 | public interface IAdtSubmodelModelFactory 7 | { 8 | Submodel GetSubmodel(AdtSubmodelAndSmcInformation information); 9 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS_WebApp_AASX_File_Server 6 | 8307df6a-cd8c-45e8-9ab0-2cbc62a85639 7 | Linux 8 | ..\.. 9 | aas-aasxfile-server:latest 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/Attributes/ValidateModelStateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc.ModelBinding; 7 | 8 | namespace AAS.API.Attributes 9 | { 10 | /// 11 | /// Model state validation attribute 12 | /// 13 | public class ValidateModelStateAttribute : ActionFilterAttribute 14 | { 15 | /// 16 | /// Called before the action method is invoked 17 | /// 18 | /// 19 | public override void OnActionExecuting(ActionExecutingContext context) 20 | { 21 | // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ 22 | var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 23 | if (descriptor != null) 24 | { 25 | foreach (var parameter in descriptor.MethodInfo.GetParameters()) 26 | { 27 | object args = null; 28 | if (context.ActionArguments.ContainsKey(parameter.Name)) 29 | { 30 | args = context.ActionArguments[parameter.Name]; 31 | } 32 | 33 | ValidateAttributes(parameter, args, context.ModelState); 34 | } 35 | } 36 | 37 | if (!context.ModelState.IsValid) 38 | { 39 | context.Result = new BadRequestObjectResult(context.ModelState); 40 | } 41 | } 42 | 43 | private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) 44 | { 45 | foreach (var attributeData in parameter.CustomAttributes) 46 | { 47 | var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 48 | 49 | var validationAttribute = attributeInstance as ValidationAttribute; 50 | if (validationAttribute != null) 51 | { 52 | var isValid = validationAttribute.IsValid(args); 53 | if (!isValid) 54 | { 55 | modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build 9 | WORKDIR /src 10 | COPY ["src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj", "src/aas-api-webapp-aasxfile/"] 11 | RUN dotnet restore "src/aas-api-webapp-aasxfile/AAS WebApp AASX File Server.csproj" 12 | COPY . . 13 | WORKDIR "/src/src/aas-api-webapp-aasxfile" 14 | RUN dotnet build "AAS WebApp AASX File Server.csproj" -c Release -o /app/build 15 | 16 | FROM build AS publish 17 | RUN dotnet publish "AAS WebApp AASX File Server.csproj" -c Release -o /app/publish 18 | 19 | FROM base AS final 20 | WORKDIR /app 21 | COPY --from=publish /app/publish . 22 | ENTRYPOINT ["dotnet", "AAS WebApp AASX File Server.dll"] -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/Filters/BasePathFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | using Swashbuckle.AspNetCore.Swagger; 4 | using Swashbuckle.AspNetCore.SwaggerGen; 5 | using Microsoft.OpenApi.Models; 6 | 7 | namespace AAS.API.WebApp.Filters 8 | { 9 | /// 10 | /// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths 11 | /// 12 | public class BasePathFilter : IDocumentFilter 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// BasePath to remove from Operations 18 | public BasePathFilter(string basePath) 19 | { 20 | BasePath = basePath; 21 | } 22 | 23 | /// 24 | /// Gets the BasePath of the Swagger Doc 25 | /// 26 | /// The BasePath of the Swagger Doc 27 | public string BasePath { get; } 28 | 29 | /// 30 | /// Apply the filter 31 | /// 32 | /// OpenApiDocument 33 | /// FilterContext 34 | public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 35 | { 36 | swaggerDoc.Servers.Add(new OpenApiServer() { Url = this.BasePath }); 37 | 38 | var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(this.BasePath)).ToList(); 39 | 40 | foreach (var path in pathsToModify) 41 | { 42 | if (path.Key.StartsWith(this.BasePath)) 43 | { 44 | string newKey = Regex.Replace(path.Key, $"^{this.BasePath}", string.Empty); 45 | swaggerDoc.Paths.Remove(path.Key); 46 | swaggerDoc.Paths.Add(newKey, path.Value); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.AASXFile.Server 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50554", 7 | "sslPort": 44376 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger/", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "AAS_WebApp_AASX_File_Server": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "swagger/", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 33 | "publishAllPorts": true, 34 | "useSSL": true 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AASX_FILESERVICE_BLOBSTORAGEURL": "https://aasxstoragejm.blob.core.windows.net/" 10 | } 11 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "microsoft.onmicrosoft.com", 5 | "ClientId": "b285565d-2793-4b48-9deb-73ac063a8ad6", 6 | "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", 7 | "AllowWebApiToBeAuthorizedByACL": true 8 | }, 9 | "Logging": { 10 | "LogLevel": { 11 | "Default": "Information", 12 | "Microsoft": "Warning", 13 | "Microsoft.Hosting.Lifetime": "Information" 14 | } 15 | }, 16 | "AllowedHosts": "*", 17 | "AASX_FILESERVICE_CONTAINERNAME": "aasxfiles", 18 | "OPENAPI_JSON_VERSION_2": false 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/aas-api-webapp-aasxfile/wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/AAS WebApp Discovery.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS_WebApp_Discovery 6 | b31c5ef0-d1cd-441a-801e-4a4c183ad995 7 | Linux 8 | ..\.. 9 | aas-discovery-server:latest 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Never 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Attributes/ValidateModelStateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc.ModelBinding; 7 | 8 | namespace AAS.API.Attributes 9 | { 10 | /// 11 | /// Model state validation attribute 12 | /// 13 | public class ValidateModelStateAttribute : ActionFilterAttribute 14 | { 15 | /// 16 | /// Called before the action method is invoked 17 | /// 18 | /// 19 | public override void OnActionExecuting(ActionExecutingContext context) 20 | { 21 | // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ 22 | var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 23 | if (descriptor != null) 24 | { 25 | foreach (var parameter in descriptor.MethodInfo.GetParameters()) 26 | { 27 | object args = null; 28 | if (context.ActionArguments.ContainsKey(parameter.Name)) 29 | { 30 | args = context.ActionArguments[parameter.Name]; 31 | } 32 | 33 | ValidateAttributes(parameter, args, context.ModelState); 34 | } 35 | } 36 | 37 | if (!context.ModelState.IsValid) 38 | { 39 | context.Result = new BadRequestObjectResult(context.ModelState); 40 | } 41 | } 42 | 43 | private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) 44 | { 45 | foreach (var attributeData in parameter.CustomAttributes) 46 | { 47 | var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 48 | 49 | var validationAttribute = attributeInstance as ValidationAttribute; 50 | if (validationAttribute != null) 51 | { 52 | var isValid = validationAttribute.IsValid(args); 53 | if (!isValid) 54 | { 55 | modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build 9 | WORKDIR /src 10 | COPY ["src/aas-api-webapp-discovery/AAS WebApp Discovery.csproj", "src/aas-api-webapp-discovery/"] 11 | RUN dotnet restore "src/aas-api-webapp-discovery/AAS WebApp Discovery.csproj" 12 | COPY . . 13 | WORKDIR "/src/src/aas-api-webapp-discovery" 14 | RUN dotnet build "AAS WebApp Discovery.csproj" -c Release -o /app/build 15 | 16 | FROM build AS publish 17 | RUN dotnet publish "AAS WebApp Discovery.csproj" -c Release -o /app/publish 18 | 19 | FROM base AS final 20 | WORKDIR /app 21 | COPY --from=publish /app/publish . 22 | ENTRYPOINT ["dotnet", "AAS WebApp Discovery.dll"] -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Filters/BasePathFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | using Swashbuckle.AspNetCore.Swagger; 4 | using Swashbuckle.AspNetCore.SwaggerGen; 5 | using Microsoft.OpenApi.Models; 6 | 7 | namespace AAS.API.WebApp.Filters 8 | { 9 | /// 10 | /// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths 11 | /// 12 | public class BasePathFilter : IDocumentFilter 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// BasePath to remove from Operations 18 | public BasePathFilter(string basePath) 19 | { 20 | BasePath = basePath; 21 | } 22 | 23 | /// 24 | /// Gets the BasePath of the Swagger Doc 25 | /// 26 | /// The BasePath of the Swagger Doc 27 | public string BasePath { get; } 28 | 29 | /// 30 | /// Apply the filter 31 | /// 32 | /// OpenApiDocument 33 | /// FilterContext 34 | public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 35 | { 36 | swaggerDoc.Servers.Add(new OpenApiServer() { Url = this.BasePath }); 37 | 38 | var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(this.BasePath)).ToList(); 39 | 40 | foreach (var path in pathsToModify) 41 | { 42 | if (path.Key.StartsWith(this.BasePath)) 43 | { 44 | string newKey = Regex.Replace(path.Key, $"^{this.BasePath}", string.Empty); 45 | swaggerDoc.Paths.Remove(path.Key); 46 | swaggerDoc.Paths.Add(newKey, path.Value); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Models/IdentifierKeyValuePairModelBinder.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc.ModelBinding; 4 | using Newtonsoft.Json; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.Discovery.Models 11 | { 12 | /// 13 | /// 14 | /// 15 | public class IdentifierKeyValuePairModelBinder : IModelBinder 16 | { 17 | /// 18 | /// 19 | /// 20 | public Task BindModelAsync(ModelBindingContext bindingContext) 21 | { 22 | // Specify a default argument name if none is set by ModelBinderAttribute 23 | var modelName = bindingContext.ModelName; 24 | if (String.IsNullOrEmpty(modelName)) 25 | { 26 | modelName = "model"; 27 | } 28 | 29 | // Try to fetch the value of the argument by name 30 | var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); 31 | if (valueProviderResult == ValueProviderResult.None) 32 | { 33 | return Task.CompletedTask; 34 | } 35 | 36 | IdentifierKeyValuePair result = JsonConvert.DeserializeObject(valueProviderResult.FirstValue); 37 | bindingContext.Result = ModelBindingResult.Success(result); 38 | 39 | return Task.CompletedTask; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Models/IdentifierKeyValuePairModelBinderProvider.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Mvc.ModelBinding; 3 | 4 | namespace AAS.API.Discovery.Models 5 | { 6 | /// 7 | /// 8 | /// 9 | public class IdentifierKeyValuePairModelBinderProvider : IModelBinderProvider 10 | { 11 | /// 12 | /// 13 | /// 14 | public IModelBinder GetBinder(ModelBinderProviderContext context) 15 | { 16 | if (context.Metadata.ModelType == typeof(IdentifierKeyValuePair)) 17 | return new IdentifierKeyValuePairModelBinder(); 18 | 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.Discovery.Server 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:36073", 7 | "sslPort": 44353 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "AAS_WebApp_Discovery": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "swagger", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 33 | "publishAllPorts": true, 34 | "useSSL": true 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "ADT_SERVICE_URL": "https://hack2021aasadt.api.weu.digitaltwins.azure.net" 10 | } 11 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "microsoft.onmicrosoft.com", 5 | "ClientId": "b285565d-2793-4b48-9deb-73ac063a8ad6", 6 | "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", 7 | "AllowWebApiToBeAuthorizedByACL": true 8 | }, 9 | "Logging": { 10 | "LogLevel": { 11 | "Default": "Information", 12 | "Microsoft": "Warning", 13 | "Microsoft.Hosting.Lifetime": "Information" 14 | } 15 | }, 16 | "AllowedHosts": "*", 17 | "OPENAPI_JSON_VERSION_2": false 18 | } 19 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/aas-api-webapp-discovery/wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "6.0.0", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-full/AAS WebApp full.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | IO.Swagger 4 | IO.Swagger 5 | net6.0 6 | true 7 | true 8 | AASAPIServerFull 9 | AASAPIServerFull 10 | AAS.API.Server.Full 11 | bf8383c6-1e08-4107-b128-89b6ddb0562f 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Attributes/ValidateModelStateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc.ModelBinding; 7 | 8 | namespace AAS.API.Attributes 9 | { 10 | /// 11 | /// Model state validation attribute 12 | /// 13 | public class ValidateModelStateAttribute : ActionFilterAttribute 14 | { 15 | /// 16 | /// Called before the action method is invoked 17 | /// 18 | /// 19 | public override void OnActionExecuting(ActionExecutingContext context) 20 | { 21 | // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ 22 | var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 23 | if (descriptor != null) 24 | { 25 | foreach (var parameter in descriptor.MethodInfo.GetParameters()) 26 | { 27 | object args = null; 28 | if (context.ActionArguments.ContainsKey(parameter.Name)) 29 | { 30 | args = context.ActionArguments[parameter.Name]; 31 | } 32 | 33 | ValidateAttributes(parameter, args, context.ModelState); 34 | } 35 | } 36 | 37 | if (!context.ModelState.IsValid) 38 | { 39 | context.Result = new BadRequestObjectResult(context.ModelState); 40 | } 41 | } 42 | 43 | private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) 44 | { 45 | foreach (var attributeData in parameter.CustomAttributes) 46 | { 47 | var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 48 | 49 | var validationAttribute = attributeInstance as ValidationAttribute; 50 | if (validationAttribute != null) 51 | { 52 | var isValid = validationAttribute.IsValid(args); 53 | if (!isValid) 54 | { 55 | modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build 9 | WORKDIR /src 10 | COPY ["src/aas-api-webapp-full/AAS WebApp full.csproj", "src/aas-api-webapp-full/"] 11 | RUN dotnet restore "src/aas-api-webapp-full/AAS WebApp full.csproj" 12 | COPY . . 13 | WORKDIR "/src/src/aas-api-webapp-full" 14 | RUN dotnet build "AAS WebApp full.csproj" -c Release -o /app/build 15 | 16 | FROM build AS publish 17 | RUN dotnet publish "AAS WebApp full.csproj" -c Release -o /app/publish 18 | 19 | FROM base AS final 20 | WORKDIR /app 21 | COPY --from=publish /app/publish . 22 | ENTRYPOINT ["dotnet", "AASAPIServerFull.dll"] -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Filters/BasePathFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | using Swashbuckle.AspNetCore.Swagger; 4 | using Swashbuckle.AspNetCore.SwaggerGen; 5 | using Microsoft.OpenApi.Models; 6 | 7 | namespace AAS.API.WebApp.Filters 8 | { 9 | /// 10 | /// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths 11 | /// 12 | public class BasePathFilter : IDocumentFilter 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// BasePath to remove from Operations 18 | public BasePathFilter(string basePath) 19 | { 20 | BasePath = basePath; 21 | } 22 | 23 | /// 24 | /// Gets the BasePath of the Swagger Doc 25 | /// 26 | /// The BasePath of the Swagger Doc 27 | public string BasePath { get; } 28 | 29 | /// 30 | /// Apply the filter 31 | /// 32 | /// OpenApiDocument 33 | /// FilterContext 34 | public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 35 | { 36 | swaggerDoc.Servers.Add(new OpenApiServer() { Url = this.BasePath }); 37 | 38 | var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(this.BasePath)).ToList(); 39 | 40 | foreach (var path in pathsToModify) 41 | { 42 | if (path.Key.StartsWith(this.BasePath)) 43 | { 44 | string newKey = Regex.Replace(path.Key, $"^{this.BasePath}", string.Empty); 45 | swaggerDoc.Paths.Remove(path.Key); 46 | swaggerDoc.Paths.Add(newKey, path.Value); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Models/IdentifierKeyValuePairModelBinder.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc.ModelBinding; 4 | using Newtonsoft.Json; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.Registry.Models 11 | { 12 | /// 13 | /// 14 | /// 15 | public class IdentifierKeyValuePairModelBinder : IModelBinder 16 | { 17 | /// 18 | /// 19 | /// 20 | public Task BindModelAsync(ModelBindingContext bindingContext) 21 | { 22 | // Specify a default argument name if none is set by ModelBinderAttribute 23 | var modelName = bindingContext.ModelName; 24 | if (String.IsNullOrEmpty(modelName)) 25 | { 26 | modelName = "model"; 27 | } 28 | 29 | // Try to fetch the value of the argument by name 30 | var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); 31 | if (valueProviderResult == ValueProviderResult.None) 32 | { 33 | return Task.CompletedTask; 34 | } 35 | 36 | IdentifierKeyValuePair result = JsonConvert.DeserializeObject(valueProviderResult.FirstValue); 37 | bindingContext.Result = ModelBindingResult.Success(result); 38 | 39 | return Task.CompletedTask; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Models/IdentifierKeyValuePairModelBinderProvider.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Mvc.ModelBinding; 3 | 4 | namespace AAS.API.Registry.Models 5 | { 6 | /// 7 | /// 8 | /// 9 | public class IdentifierKeyValuePairModelBinderProvider : IModelBinderProvider 10 | { 11 | /// 12 | /// 13 | /// 14 | public IModelBinder GetBinder(ModelBinderProviderContext context) 15 | { 16 | if (context.Metadata.ModelType == typeof(IdentifierKeyValuePair)) 17 | return new IdentifierKeyValuePairModelBinder(); 18 | 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.AspNetCore; 3 | 4 | namespace AAS.API.Full.Server 5 | { 6 | /// 7 | /// Program 8 | /// 9 | public class Program 10 | { 11 | /// 12 | /// Main 13 | /// 14 | /// 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | /// 21 | /// Create the web host builder. 22 | /// 23 | /// 24 | /// IWebHostBuilder 25 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 26 | WebHost.CreateDefaultBuilder(args) 27 | .UseStartup(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50352/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "swagger/", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "web": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "swagger", 23 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | } 27 | }, 28 | "Docker": { 29 | "commandName": "Docker", 30 | "launchBrowser": true, 31 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 32 | "publishAllPorts": true, 33 | "useSSL": true 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-full/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "ADT_SERVICE_URL": "https://hack2021aasadt.api.weu.digitaltwins.azure.net", 11 | "AASX_FILESERVICE_BLOBSTORAGEURL": "https://aasxstoragejm.blob.core.windows.net/" 12 | } 13 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "microsoft.onmicrosoft.com", 5 | "ClientId": "b285565d-2793-4b48-9deb-73ac063a8ad6", 6 | "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", 7 | "AllowWebApiToBeAuthorizedByACL": true 8 | }, 9 | "Logging": { 10 | "IncludeScopes": false, 11 | "LogLevel": { 12 | "Default": "Information", 13 | "System": "Information", 14 | "Microsoft": "Information" 15 | } 16 | }, 17 | "AASX_FILESERVICE_CONTAINERNAME": "aasxfiles", 18 | "OPENAPI_JSON_VERSION_2": false 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/aas-api-webapp-full/wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/AAS WebApp Registry.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS_WebApp_Registry 6 | c7576273-fad3-4cb6-8ad2-9e25bafa9106 7 | Linux 8 | ..\.. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Attributes/ValidateModelStateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc.ModelBinding; 7 | 8 | namespace AAS.API.Attributes 9 | { 10 | /// 11 | /// Model state validation attribute 12 | /// 13 | public class ValidateModelStateAttribute : ActionFilterAttribute 14 | { 15 | /// 16 | /// Called before the action method is invoked 17 | /// 18 | /// 19 | public override void OnActionExecuting(ActionExecutingContext context) 20 | { 21 | // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ 22 | var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 23 | if (descriptor != null) 24 | { 25 | foreach (var parameter in descriptor.MethodInfo.GetParameters()) 26 | { 27 | object args = null; 28 | if (context.ActionArguments.ContainsKey(parameter.Name)) 29 | { 30 | args = context.ActionArguments[parameter.Name]; 31 | } 32 | 33 | ValidateAttributes(parameter, args, context.ModelState); 34 | } 35 | } 36 | 37 | if (!context.ModelState.IsValid) 38 | { 39 | context.Result = new BadRequestObjectResult(context.ModelState); 40 | } 41 | } 42 | 43 | private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) 44 | { 45 | foreach (var attributeData in parameter.CustomAttributes) 46 | { 47 | var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 48 | 49 | var validationAttribute = attributeInstance as ValidationAttribute; 50 | if (validationAttribute != null) 51 | { 52 | var isValid = validationAttribute.IsValid(args); 53 | if (!isValid) 54 | { 55 | modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build 9 | WORKDIR /src 10 | COPY ["NuGet.Config", "."] 11 | COPY ["src/aas-api-webapp-registry/AAS WebApp Registry.csproj", "src/aas-api-webapp-registry/"] 12 | COPY ["src/aas-registry-service/AAS Registry Service.csproj", "src/aas-registry-service/"] 13 | COPY ["src/aas-api-models/AAS API Models.csproj", "src/aas-api-models/"] 14 | COPY ["src/aas-services-support/AAS Services Support.csproj", "src/aas-services-support/"] 15 | RUN dotnet restore "src/aas-api-webapp-registry/AAS WebApp Registry.csproj" 16 | COPY . . 17 | WORKDIR "/src/src/aas-api-webapp-registry" 18 | RUN dotnet build "AAS WebApp Registry.csproj" -c Release -o /app/build 19 | 20 | FROM build AS publish 21 | RUN dotnet publish "AAS WebApp Registry.csproj" -c Release -o /app/publish /p:UseAppHost=false 22 | 23 | FROM base AS final 24 | WORKDIR /app 25 | COPY --from=publish /app/publish . 26 | ENTRYPOINT ["dotnet", "AAS WebApp Registry.dll"] -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Filters/BasePathFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | using Swashbuckle.AspNetCore.Swagger; 4 | using Swashbuckle.AspNetCore.SwaggerGen; 5 | using Microsoft.OpenApi.Models; 6 | 7 | namespace AAS.API.WebApp.Filters 8 | { 9 | /// 10 | /// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths 11 | /// 12 | public class BasePathFilter : IDocumentFilter 13 | { 14 | /// 15 | /// Constructor 16 | /// 17 | /// BasePath to remove from Operations 18 | public BasePathFilter(string basePath) 19 | { 20 | BasePath = basePath; 21 | } 22 | 23 | /// 24 | /// Gets the BasePath of the Swagger Doc 25 | /// 26 | /// The BasePath of the Swagger Doc 27 | public string BasePath { get; } 28 | 29 | /// 30 | /// Apply the filter 31 | /// 32 | /// OpenApiDocument 33 | /// FilterContext 34 | public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 35 | { 36 | swaggerDoc.Servers.Add(new OpenApiServer() { Url = this.BasePath }); 37 | 38 | var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(this.BasePath)).ToList(); 39 | 40 | foreach (var path in pathsToModify) 41 | { 42 | if (path.Key.StartsWith(this.BasePath)) 43 | { 44 | string newKey = Regex.Replace(path.Key, $"^{this.BasePath}", string.Empty); 45 | swaggerDoc.Paths.Remove(path.Key); 46 | swaggerDoc.Paths.Add(newKey, path.Value); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Models/IdentifierKeyValuePairModelBinder.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc.ModelBinding; 4 | using Newtonsoft.Json; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.Registry.Models 11 | { 12 | /// 13 | /// 14 | /// 15 | public class IdentifierKeyValuePairModelBinder : IModelBinder 16 | { 17 | /// 18 | /// 19 | /// 20 | public Task BindModelAsync(ModelBindingContext bindingContext) 21 | { 22 | // Specify a default argument name if none is set by ModelBinderAttribute 23 | var modelName = bindingContext.ModelName; 24 | if (String.IsNullOrEmpty(modelName)) 25 | { 26 | modelName = "model"; 27 | } 28 | 29 | // Try to fetch the value of the argument by name 30 | var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); 31 | if (valueProviderResult == ValueProviderResult.None) 32 | { 33 | return Task.CompletedTask; 34 | } 35 | 36 | IdentifierKeyValuePair result = JsonConvert.DeserializeObject(valueProviderResult.FirstValue); 37 | bindingContext.Result = ModelBindingResult.Success(result); 38 | 39 | return Task.CompletedTask; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Models/IdentifierKeyValuePairModelBinderProvider.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Mvc.ModelBinding; 3 | 4 | namespace AAS.API.Registry.Models 5 | { 6 | /// 7 | /// 8 | /// 9 | public class IdentifierKeyValuePairModelBinderProvider : IModelBinderProvider 10 | { 11 | /// 12 | /// 13 | /// 14 | public IModelBinder GetBinder(ModelBinderProviderContext context) 15 | { 16 | if (context.Metadata.ModelType == typeof(IdentifierKeyValuePair)) 17 | return new IdentifierKeyValuePairModelBinder(); 18 | 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace AAS.API.Registry.Server 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41891", 8 | "sslPort": 44362 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "AAS_WebApp_Registry": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "swagger", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 33 | "publishAllPorts": true, 34 | "useSSL": true 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "fdpo.onmicrosoft.com", 5 | "ClientId": "f8ed554d-073a-49f8-971e-c6b3ca43e3d6", 6 | "TenantId": "16b3c013-d300-468d-ac64-7eda0820b6d3", 7 | "AllowWebApiToBeAuthorizedByACL": true 8 | }, 9 | "Logging": { 10 | "LogLevel": { 11 | "Default": "Information", 12 | "Microsoft": "Warning", 13 | "Microsoft.Hosting.Lifetime": "Information" 14 | } 15 | }, 16 | "AllowedHosts": "*", 17 | "OPENAPI_JSON_VERSION_2": false, 18 | "aas-registry-service-useRedisCache": false 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/aas-api-webapp-registry/wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/AAS WebApp Repository.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | IO.Swagger 4 | IO.Swagger 5 | net6.0 6 | true 7 | true 8 | AASWebAppRepository 9 | IO.Swagger 10 | AAS.API.Repository 11 | 93593822-14b3-46e2-abbf-d9ea7cdc447f 12 | Linux 13 | ..\.. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/AAS WebApp Repository.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Attributes/ValidateModelStateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Reflection; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.Controllers; 5 | using Microsoft.AspNetCore.Mvc.Filters; 6 | using Microsoft.AspNetCore.Mvc.ModelBinding; 7 | 8 | namespace Aas.Api.Repository.Attributes 9 | { 10 | /// 11 | /// Model state validation attribute 12 | /// 13 | public class ValidateModelStateAttribute : ActionFilterAttribute 14 | { 15 | /// 16 | /// Called before the action method is invoked 17 | /// 18 | /// 19 | public override void OnActionExecuting(ActionExecutingContext context) 20 | { 21 | // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ 22 | var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 23 | if (descriptor != null) 24 | { 25 | foreach (var parameter in descriptor.MethodInfo.GetParameters()) 26 | { 27 | object args = null; 28 | if (context.ActionArguments.ContainsKey(parameter.Name)) 29 | { 30 | args = context.ActionArguments[parameter.Name]; 31 | } 32 | 33 | ValidateAttributes(parameter, args, context.ModelState); 34 | } 35 | } 36 | 37 | if (!context.ModelState.IsValid) 38 | { 39 | context.Result = new BadRequestObjectResult(context.ModelState); 40 | } 41 | } 42 | 43 | private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) 44 | { 45 | foreach (var attributeData in parameter.CustomAttributes) 46 | { 47 | var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 48 | 49 | var validationAttribute = attributeInstance as ValidationAttribute; 50 | if (validationAttribute != null) 51 | { 52 | var isValid = validationAttribute.IsValid(args); 53 | if (!isValid) 54 | { 55 | modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Dockerfile: -------------------------------------------------------------------------------- 1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. 2 | 3 | FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base 4 | WORKDIR /app 5 | EXPOSE 80 6 | EXPOSE 443 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build 9 | WORKDIR /src 10 | COPY ["NuGet.Config", "."] 11 | COPY ["src/aas-api-webapp-repository/AAS WebApp Repository.csproj", "src/aas-api-webapp-repository/"] 12 | COPY ["src/aas-api-repository-adt/AasRepositoryAdt.csproj", "src/aas-api-repository-adt/"] 13 | COPY ["src/AAS ADT SDK/AAS ADT SDK.csproj", "src/AAS ADT SDK/"] 14 | COPY ["src/aas-services-support/AAS Services Support.csproj", "src/aas-services-support/"] 15 | COPY ["src/aas-api-models/AAS API Models.csproj", "src/aas-api-models/"] 16 | COPY ["src/aas-repository/AAS Repository.csproj", "src/aas-repository/"] 17 | RUN dotnet restore "src/aas-api-webapp-repository/AAS WebApp Repository.csproj" 18 | COPY . . 19 | WORKDIR "/src/src/aas-api-webapp-repository" 20 | RUN dotnet build "AAS WebApp Repository.csproj" -c Release -o /app/build 21 | 22 | FROM build AS publish 23 | RUN dotnet publish "AAS WebApp Repository.csproj" -c Release -o /app/publish /p:UseAppHost=false 24 | 25 | FROM base AS final 26 | WORKDIR /app 27 | COPY --from=publish /app/publish . 28 | ENTRYPOINT ["dotnet", "AASWebAppRepository.dll"] -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Filters/BasePathFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | using Microsoft.OpenApi.Models; 4 | using Swashbuckle.AspNetCore.SwaggerGen; 5 | 6 | namespace Aas.Api.Repository.Filters 7 | { 8 | /// 9 | /// BasePath Document Filter sets BasePath property of Swagger and removes it from the individual URL paths 10 | /// 11 | public class BasePathFilter : IDocumentFilter 12 | { 13 | /// 14 | /// Constructor 15 | /// 16 | /// BasePath to remove from Operations 17 | public BasePathFilter(string basePath) 18 | { 19 | BasePath = basePath; 20 | } 21 | 22 | /// 23 | /// Gets the BasePath of the Swagger Doc 24 | /// 25 | /// The BasePath of the Swagger Doc 26 | public string BasePath { get; } 27 | 28 | /// 29 | /// Apply the filter 30 | /// 31 | /// OpenApiDocument 32 | /// FilterContext 33 | public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 34 | { 35 | swaggerDoc.Servers.Add(new OpenApiServer() { Url = this.BasePath }); 36 | 37 | var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(this.BasePath)).ToList(); 38 | 39 | foreach (var path in pathsToModify) 40 | { 41 | if (path.Key.StartsWith(this.BasePath)) 42 | { 43 | string newKey = Regex.Replace(path.Key, $"^{this.BasePath}", string.Empty); 44 | swaggerDoc.Paths.Remove(path.Key); 45 | swaggerDoc.Paths.Add(newKey, path.Value); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Mapper/AutoMapper/DataTypeDefXsdProfile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AasCore.Aas3_0_RC02; 3 | using AutoMapper; 4 | 5 | namespace AAS.API.Repository.AutoMapper 6 | { 7 | 8 | public class DataTypeDefXsdProfile : Profile 9 | { 10 | public DataTypeDefXsdProfile() 11 | { 12 | CreateMap() 13 | .ConvertUsing(new StringToDataTypeDefXsdConverter()); 14 | } 15 | } 16 | 17 | public class StringToDataTypeDefXsdConverter : ITypeConverter 18 | { 19 | public DataTypeDefXsd? Convert(string source, DataTypeDefXsd? destination, ResolutionContext context) 20 | { 21 | var asdf = source.StartsWith("xs:", StringComparison.InvariantCultureIgnoreCase) 22 | ? source[3..source.Length] 23 | : source; 24 | var success = Enum.TryParse(asdf, true,out var result); 25 | 26 | if (success) 27 | { 28 | return result; 29 | } 30 | 31 | return null; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Mapper/JObjectToAasObjectMapperStrategy.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | 3 | namespace AAS.API.Repository 4 | { 5 | public interface ObjectMapperStrategy 6 | { 7 | public T map(JObject obj); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Mapper/JObjectToPropertyMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AasCore.Aas3_0_RC02; 3 | using AutoMapper; 4 | using Newtonsoft.Json.Linq; 5 | 6 | namespace AAS.API.Repository 7 | { 8 | public class JObjectToPropertyMapper : ObjectMapperStrategy 9 | { 10 | private readonly IMapper _autoMapper; 11 | public JObjectToPropertyMapper(IMapper autoMapper) 12 | { 13 | _autoMapper = autoMapper ?? 14 | throw new ArgumentNullException(nameof(autoMapper)); 15 | } 16 | 17 | public Property map(JObject obj) 18 | { 19 | var valueType = obj.GetValue("valueType").ToString() == null 20 | ? throw new ArgumentNullException() 21 | : _autoMapper.Map(obj.GetValue("valueType").ToString()); 22 | var property = new Property(valueType); 23 | property.Value = obj.GetValue("value").ToString(); 24 | property.ValueId = obj.GetValue("valueId").ToObject(); 25 | property.AddSubmodelElementValues(obj); 26 | return property; 27 | } 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Models/IdentifierKeyValuePairModelBinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using AAS.API.Models; 4 | using Microsoft.AspNetCore.Mvc.ModelBinding; 5 | using Newtonsoft.Json; 6 | 7 | namespace Aas.Api.Repository.Models 8 | { 9 | /// 10 | /// 11 | /// 12 | public class IdentifierKeyValuePairModelBinder : IModelBinder 13 | { 14 | /// 15 | /// 16 | /// 17 | public Task BindModelAsync(ModelBindingContext bindingContext) 18 | { 19 | // Specify a default argument name if none is set by ModelBinderAttribute 20 | var modelName = bindingContext.ModelName; 21 | if (String.IsNullOrEmpty(modelName)) 22 | { 23 | modelName = "model"; 24 | } 25 | 26 | // Try to fetch the value of the argument by name 27 | var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); 28 | if (valueProviderResult == ValueProviderResult.None) 29 | { 30 | return Task.CompletedTask; 31 | } 32 | 33 | IdentifierKeyValuePair result = JsonConvert.DeserializeObject(valueProviderResult.FirstValue); 34 | bindingContext.Result = ModelBindingResult.Success(result); 35 | 36 | return Task.CompletedTask; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Models/IdentifierKeyValuePairModelBinderProvider.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Microsoft.AspNetCore.Mvc.ModelBinding; 3 | 4 | namespace Aas.Api.Repository.Models 5 | { 6 | /// 7 | /// 8 | /// 9 | public class IdentifierKeyValuePairModelBinderProvider : IModelBinderProvider 10 | { 11 | /// 12 | /// 13 | /// 14 | public IModelBinder GetBinder(ModelBinderProviderContext context) 15 | { 16 | if (context.Metadata.ModelType == typeof(IdentifierKeyValuePair)) 17 | return new IdentifierKeyValuePairModelBinder(); 18 | 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | 6 | namespace Aas.Api.Repository 7 | { 8 | /// 9 | /// Program 10 | /// 11 | public class Program 12 | { 13 | /// 14 | /// Main 15 | /// 16 | /// 17 | public static void Main(string[] args) 18 | { 19 | CreateWebHostBuilder(args).Build().Run(); 20 | } 21 | 22 | /// 23 | /// Create the web host builder. 24 | /// 25 | /// 26 | /// IWebHostBuilder 27 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 28 | WebHost.CreateDefaultBuilder(args) 29 | .ConfigureLogging(logging => 30 | { 31 | logging.ClearProviders(); 32 | logging.AddConsole(); 33 | }) 34 | .UseStartup(); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:50352/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "swagger/", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "web": { 20 | "commandName": "Project", 21 | "launchBrowser": false, 22 | "launchUrl": "swagger", 23 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | } 27 | }, 28 | "Docker": { 29 | "commandName": "Docker", 30 | "launchBrowser": true, 31 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", 32 | "publishAllPorts": true, 33 | "useSSL": true 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "AzureAd": { 3 | "Instance": "https://login.microsoftonline.com/", 4 | "Domain": "microsoft.onmicrosoft.com", 5 | "ClientId": "b285565d-2793-4b48-9deb-73ac063a8ad6", 6 | "TenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", 7 | "AllowWebApiToBeAuthorizedByACL": true 8 | }, 9 | "Logging": { 10 | "IncludeScopes": false, 11 | "LogLevel": { 12 | "Default": "Information", 13 | "System": "Information", 14 | "Microsoft": "Information" 15 | } 16 | }, 17 | "ADT_SERVICE_URL": "https://hack2021aasadt.api.weu.digitaltwins.azure.net", 18 | "OPENAPI_JSON_VERSION_2": false 19 | } 20 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [] 5 | } -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/aas-api-webapp-repository/wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/aas-discovery-service/AAS Discovery Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS.API.Discovery 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/aas-discovery-service/AASDiscovery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using AAS.API.Interfaces; 4 | using AAS.API.Services; 5 | 6 | namespace AAS.API.Discovery 7 | { 8 | public interface AASDiscovery : BasicDiscovery 9 | { 10 | } 11 | 12 | public class AASDiscoveryException : AASServiceException 13 | { 14 | // 15 | // Summary: 16 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 17 | // error message. 18 | // 19 | // Parameters: 20 | // message: 21 | // The message that describes the error. 22 | public AASDiscoveryException(string message) : base(message) 23 | { 24 | } 25 | // 26 | // Summary: 27 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 28 | // error message, HTTP status code and a reference to the inner exception that is 29 | // the cause of this exception. 30 | // 31 | // Parameters: 32 | // message: 33 | // The error message that explains the reason for the exception. 34 | // 35 | // innerException: 36 | // The exception that is the cause of the current exception, or a null reference 37 | // (Nothing in Visual Basic) if no inner exception is specified. 38 | public AASDiscoveryException(string message, Exception? innerException) : base(message, innerException) 39 | { 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/aas-discovery-service/AASDiscoveryFactory.cs: -------------------------------------------------------------------------------- 1 | using Azure.Core.Pipeline; 2 | using Azure.DigitalTwins.Core; 3 | using Azure.Identity; 4 | using System; 5 | using System.Net.Http; 6 | 7 | namespace AAS.API.Discovery 8 | { 9 | public class AASDiscoveryFactory 10 | { 11 | public AASDiscovery CreateAASDiscoveryForADT(string adtInstanceURL) 12 | { 13 | // First use DefaultAzureCredentials and second EnvironmentCredential to enable local docker execution 14 | var credentials = new ChainedTokenCredential(new DefaultAzureCredential(), new EnvironmentCredential()); 15 | 16 | DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceURL), 17 | credentials, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(new HttpClient()) }); 18 | 19 | return new ADTAASDiscovery(client); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/aas-registry-service-tests/AAS Registry Service Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS_Registry_Service_Tests 6 | 7 | false 8 | 9 | 06b295f3-2368-43ff-b329-5e66787de288 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | PreserveNewest 33 | 34 | 35 | Always 36 | 37 | 38 | Always 39 | 40 | 41 | Always 42 | 43 | 44 | Always 45 | 46 | 47 | Always 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/aas-registry-service-tests/Descriptor samples/sampleAASDesc.json: -------------------------------------------------------------------------------- 1 | { 2 | "identification": "https://example.org/aas/motor", 3 | "endpoints": [ 4 | { 5 | "protocolInformation": { 6 | "endpointAddress": "https://localhost:1234", 7 | "endpointProtocolVersion": "1.1" 8 | }, 9 | "interface": "AAS-1.0" 10 | }, 11 | { 12 | "protocolInformation": { 13 | "endpointAddress": "opc.tcp://localhost:4840" 14 | }, 15 | "interface": "AAS-1.0" 16 | }, 17 | { 18 | "protocolInformation": { 19 | "endpointAddress": "https://localhost:5678", 20 | "endpointProtocolVersion": "1.1", 21 | "subprotocol": "OPC UA Basic SOAP", 22 | "subprotocolBody": "ns=2;s=MyAAS", 23 | "subprotocolBodyEncoding": "application/soap+xml" 24 | }, 25 | "interface": "AAS-1.0" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /src/aas-registry-service-tests/Descriptor samples/test001AASDesc.json: -------------------------------------------------------------------------------- 1 | { 2 | "identification": "https://example.org/aas/test001", 3 | "endpoints": [ 4 | { 5 | "protocolInformation": { 6 | "endpointAddress": "https://localhost:1234", 7 | "endpointProtocolVersion": "1.1" 8 | }, 9 | "interface": "AAS-1.0" 10 | }, 11 | { 12 | "protocolInformation": { 13 | "endpointAddress": "opc.tcp://localhost:4840" 14 | }, 15 | "interface": "AAS-1.0" 16 | }, 17 | { 18 | "protocolInformation": { 19 | "endpointAddress": "https://localhost:5678", 20 | "endpointProtocolVersion": "1.1", 21 | "subprotocol": "OPC UA Basic SOAP", 22 | "subprotocolBody": "ns=2;s=MyAAS", 23 | "subprotocolBodyEncoding": "application/soap+xml" 24 | }, 25 | "interface": "AAS-1.0" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /src/aas-registry-service-tests/Descriptor samples/test001SubmodelDesc.json: -------------------------------------------------------------------------------- 1 | { 2 | "identification": "https://example.org/submodel/simpleTest", 3 | "idShort": "simpleTest", 4 | "endpoints": [ 5 | { 6 | "protocolInformation": { 7 | "endpointAddress": "https://localhost:1234", 8 | "endpointProtocolVersion": "1.1" 9 | }, 10 | "interface": "AAS-1.0" 11 | }, 12 | { 13 | "protocolInformation": { 14 | "endpointAddress": "opc.tcp://localhost:4840" 15 | }, 16 | "interface": "AAS-1.0" 17 | }, 18 | { 19 | "protocolInformation": { 20 | "endpointAddress": "https://localhost:5678", 21 | "endpointProtocolVersion": "1.1", 22 | "subprotocol": "OPC UA Basic SOAP", 23 | "subprotocolBody": "ns=2;s=MyAAS", 24 | "subprotocolBodyEncoding": "application/soap+xml" 25 | }, 26 | "interface": "AAS-1.0" 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /src/aas-registry-service-tests/Descriptor samples/testAASDescs.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "identification": "https://example.org/aas/test001", 4 | "endpoints": [ 5 | { 6 | "protocolInformation": { 7 | "endpointAddress": "https://localhost:1234", 8 | "endpointProtocolVersion": "1.1" 9 | }, 10 | "interface": "AAS-1.0" 11 | }, 12 | { 13 | "protocolInformation": { 14 | "endpointAddress": "opc.tcp://localhost:4840" 15 | }, 16 | "interface": "AAS-1.0" 17 | }, 18 | { 19 | "protocolInformation": { 20 | "endpointAddress": "https://localhost:5678", 21 | "endpointProtocolVersion": "1.1", 22 | "subprotocol": "OPC UA Basic SOAP", 23 | "subprotocolBody": "ns=2;s=MyAAS", 24 | "subprotocolBodyEncoding": "application/soap+xml" 25 | }, 26 | "interface": "AAS-1.0" 27 | } 28 | ] 29 | }, 30 | { 31 | "identification": "https://example.org/aas/test002", 32 | "endpoints": [ 33 | { 34 | "protocolInformation": { 35 | "endpointAddress": "https://localhost:1234", 36 | "endpointProtocolVersion": "1.1" 37 | }, 38 | "interface": "AAS-1.0" 39 | }, 40 | { 41 | "protocolInformation": { 42 | "endpointAddress": "opc.tcp://localhost:4840" 43 | }, 44 | "interface": "AAS-1.0" 45 | }, 46 | { 47 | "protocolInformation": { 48 | "endpointAddress": "https://localhost:5678", 49 | "endpointProtocolVersion": "1.1", 50 | "subprotocol": "OPC UA Basic SOAP", 51 | "subprotocolBody": "ns=2;s=MyAAS", 52 | "subprotocolBodyEncoding": "application/soap+xml" 53 | }, 54 | "interface": "AAS-1.0" 55 | } 56 | ] 57 | }, 58 | { 59 | "identification": "https://example.org/aas/test003", 60 | "endpoints": [ 61 | { 62 | "protocolInformation": { 63 | "endpointAddress": "https://localhost:1234", 64 | "endpointProtocolVersion": "1.1" 65 | }, 66 | "interface": "AAS-1.0" 67 | }, 68 | { 69 | "protocolInformation": { 70 | "endpointAddress": "opc.tcp://localhost:4840" 71 | }, 72 | "interface": "AAS-1.0" 73 | }, 74 | { 75 | "protocolInformation": { 76 | "endpointAddress": "https://localhost:5678", 77 | "endpointProtocolVersion": "1.1", 78 | "subprotocol": "OPC UA Basic SOAP", 79 | "subprotocolBody": "ns=2;s=MyAAS", 80 | "subprotocolBodyEncoding": "application/soap+xml" 81 | }, 82 | "interface": "AAS-1.0" 83 | } 84 | ] 85 | } 86 | ] -------------------------------------------------------------------------------- /src/aas-registry-service-tests/appsettings.tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information", 8 | "AAS": "Debug" 9 | } 10 | }, 11 | "CosmosDb": { 12 | "Account": "https://aasregistrydb-ie63tatjrkfoy.documents.azure.com:443/" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/aas-registry-service/AAS Registry Service.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | AAS_Registry_Service 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/aas-registry-service/AASRegistry.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Services; 2 | using System; 3 | 4 | namespace AAS.API.Registry 5 | { 6 | public interface AASRegistry : AAS.API.Interfaces.Registry, AAS.API.Interfaces.SubmodelRegistry 7 | { 8 | } 9 | public class AASRegistryException : AASServiceException 10 | { 11 | // 12 | // Summary: 13 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 14 | // error message. 15 | // 16 | // Parameters: 17 | // message: 18 | // The message that describes the error. 19 | public AASRegistryException(string message) : base(message) 20 | { 21 | } 22 | // 23 | // Summary: 24 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 25 | // error message, HTTP status code and a reference to the inner exception that is 26 | // the cause of this exception. 27 | // 28 | // Parameters: 29 | // message: 30 | // The error message that explains the reason for the exception. 31 | // 32 | // innerException: 33 | // The exception that is the cause of the current exception, or a null reference 34 | // (Nothing in Visual Basic) if no inner exception is specified. 35 | public AASRegistryException(string message, Exception? innerException) : base(message, innerException) 36 | { 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/aas-registry-service/Cache.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Caching.Distributed; 2 | using Newtonsoft.Json; 3 | using System.Threading.Tasks; 4 | 5 | namespace AAS.API.Registry 6 | { 7 | public class Cache 8 | { 9 | private readonly IDistributedCache _cache; 10 | 11 | public Cache(IDistributedCache aCache) 12 | { 13 | _cache = aCache; 14 | } 15 | 16 | public async Task Get(string key) where T : class 17 | { 18 | var cachedResponse = await _cache.GetStringAsync(key); 19 | return cachedResponse == null ? null : JsonConvert.DeserializeObject(cachedResponse, 20 | new JsonSerializerSettings() { 21 | ReferenceLoopHandling = ReferenceLoopHandling.Ignore 22 | }); 23 | } 24 | 25 | public async Task Set(string key, T value, DistributedCacheEntryOptions options) where T : class 26 | { 27 | var response = JsonConvert.SerializeObject(value,new JsonSerializerSettings() { 28 | ReferenceLoopHandling = ReferenceLoopHandling.Ignore 29 | }); 30 | await _cache.SetStringAsync(key, response, options); 31 | } 32 | 33 | public async Task Clear(string key) 34 | { 35 | await _cache.RemoveAsync(key); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/aas-registry-service/CosmosDBImpl/DBAssetAdministrationShellDescriptor.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Text; 8 | using System.Text.Json.Serialization; 9 | using System.Threading.Tasks; 10 | using System.Transactions; 11 | 12 | namespace AAS.API.Registry.CosmosDBImpl 13 | { 14 | public class DBAssetAdministrationShellDescriptor 15 | { 16 | [JsonProperty("id")] 17 | public string Id { get; set; } 18 | 19 | [JsonProperty("shellDesc")] 20 | public AssetAdministrationShellDescriptor Desc { get; set; } 21 | 22 | public DBAssetAdministrationShellDescriptor(AssetAdministrationShellDescriptor shellDesc) 23 | { 24 | Desc = shellDesc; 25 | 26 | if (shellDesc != null && shellDesc.Identification != null) 27 | { 28 | Id = CreateDocumentId(shellDesc.Identification); 29 | } 30 | } 31 | 32 | public static string CreateDocumentId(string shellId) 33 | { 34 | return shellId?.Replace('/', '-').Replace('?', '_').Replace('#', '_'); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/aas-registry-service/CosmosDBImpl/DBSubmodelDescriptor.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Models; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace AAS.API.Registry.CosmosDBImpl 10 | { 11 | public class DBSubmodelDescriptor 12 | { 13 | [JsonProperty("id")] 14 | public string Id { get; set; } 15 | 16 | [JsonProperty("submodelDesc")] 17 | public SubmodelDescriptor Desc { get; set; } 18 | 19 | public DBSubmodelDescriptor(SubmodelDescriptor submodelDesc) 20 | { 21 | Desc = submodelDesc; 22 | 23 | if (submodelDesc != null && submodelDesc.Identification != null) 24 | { 25 | Id = CreateDocumentId(submodelDesc.Identification); 26 | } 27 | } 28 | 29 | public static string CreateDocumentId(string shellId) 30 | { 31 | return shellId?.Replace('/', '-').Replace('?', '_').Replace('#', '_'); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/aas-registry-service/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AAS.API.Registry 4 | { 5 | internal class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Console.WriteLine("Hello World!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/aas-repository-tests/AAS Repository Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS_Repository_Tests 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/aas-repository/AAS Repository.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0 6 | AAS.API.Repository 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/aas-repository/AASRepository.cs: -------------------------------------------------------------------------------- 1 | using AAS.API.Interfaces; 2 | using AAS.API.Services; 3 | using System; 4 | using System.Collections.Generic; 5 | using AasCore.Aas3_0_RC02; 6 | using System.Threading.Tasks; 7 | 8 | namespace AAS.API.Repository 9 | { 10 | public interface AASRepository 11 | { 12 | public List GetAllAssetAdministrationShellIds(); 13 | public Task GetAssetAdministrationShellWithId(string aasId); 14 | public Task DeleteAssetAdministrationShellWithId(string aasId); 15 | 16 | public Task> GetAllAssetAdministrationShells(); 17 | public Task CreateAssetAdministrationShell(AssetAdministrationShell shell); 18 | public Task UpdateExistingAssetAdministrationShellWithId(string aasId, AssetAdministrationShell shell); 19 | 20 | public Task CreateSubmodelReference(string aasId, Reference submodelRef); 21 | public Task DeleteSubmodelReference(string aasId, string submodelId); 22 | 23 | } 24 | 25 | public class AASRepositoryException : AASServiceException 26 | { 27 | // 28 | // Summary: 29 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 30 | // error message. 31 | // 32 | // Parameters: 33 | // message: 34 | // The message that describes the error. 35 | public AASRepositoryException(string message) : base(message) 36 | { 37 | } 38 | // 39 | // Summary: 40 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 41 | // error message, HTTP status code and a reference to the inner exception that is 42 | // the cause of this exception. 43 | // 44 | // Parameters: 45 | // message: 46 | // The error message that explains the reason for the exception. 47 | // 48 | // innerException: 49 | // The exception that is the cause of the current exception, or a null reference 50 | // (Nothing in Visual Basic) if no inner exception is specified. 51 | public AASRepositoryException(string message, Exception? innerException) : base(message, innerException) 52 | { 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/aas-repository/ISubmodelRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using AasCore.Aas3_0_RC02; 4 | 5 | namespace AAS.API.Repository 6 | { 7 | public interface ISubmodelRepository 8 | { 9 | public Task> GetAllSubmodels(); 10 | public Task GetSubmodelWithId(string submodelId); 11 | public Task CreateSubmodel(Submodel submodel); 12 | public Task UpdateExistingSubmodelWithId(string submodelIdentifier, Submodel submodel); 13 | public Task DeleteSubmodelWithId(string submodelIdentifier); 14 | 15 | } 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/aas-repository/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AAS.API.Repository 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Console.WriteLine("Hello World!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/aas-services-support-tests/AAS Services Support Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB 4 | 5 | 6 | $(VsInstallRoot)\Common7\IDE\Extensions\Microsoft\SQLDB\DAC 7 | 8 | 9 | 10.0 10 | 11 | 12 | net6.0 13 | AAS_Services_Support_Tests 14 | enable 15 | enable 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 3.1 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/aas-services-support-tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /src/aas-services-support-tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /src/aas-services-support/AAS Services Support.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | AAS.API.Services 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/aas-services-support/AAS Services Support.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /src/aas-services-support/AASServiceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace AAS.API.Services 5 | { 6 | public abstract class AASServiceException : Exception, ISerializable 7 | { 8 | // 9 | // Summary: 10 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 11 | // error message. 12 | // 13 | // Parameters: 14 | // message: 15 | // The message that describes the error. 16 | public AASServiceException(string message) : base(message) 17 | { 18 | } 19 | // 20 | // Summary: 21 | // Initializes a new instance of the Azure.RequestFailedException class with a specified 22 | // error message, HTTP status code and a reference to the inner exception that is 23 | // the cause of this exception. 24 | // 25 | // Parameters: 26 | // message: 27 | // The error message that explains the reason for the exception. 28 | // 29 | // innerException: 30 | // The exception that is the cause of the current exception, or a null reference 31 | // (Nothing in Visual Basic) if no inner exception is specified. 32 | public AASServiceException(string message, Exception? innerException) : base(message, innerException) 33 | { 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/aas-services-support/ADT Support/ADTConstants.cs: -------------------------------------------------------------------------------- 1 | namespace AAS.API.Services.ADT 2 | { 3 | public interface ADTConstants 4 | { 5 | public const string AAS_MODEL_NAME = "dtmi:digitaltwins:aas:AssetAdministrationShell;1"; 6 | public const string KEY_MODEL_NAME = "dtmi:digitaltwins:aas:Key;1"; 7 | public const string IDENTIFIERKEYVALUEPAIR_MODEL_NAME = "dtmi:digitaltwins:aas:IdentifierKeyValuePair;1"; 8 | 9 | public const string GLOBALASSETID = "globalAssetId"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/aas-services-support/ADT Support/ADTOperationsResult.cs: -------------------------------------------------------------------------------- 1 | using Azure.DigitalTwins.Core; 2 | using System.Collections.Generic; 3 | 4 | namespace AAS.API.Services.ADT 5 | { 6 | public class ADTOperationsResult 7 | { 8 | private Dictionary createdReplacedTwins; 9 | 10 | public Dictionary CreatedReplacedTwins 11 | { 12 | get { return createdReplacedTwins; } 13 | set { createdReplacedTwins = value; } 14 | } 15 | 16 | private Dictionary createdReplacedRelationships; 17 | 18 | public Dictionary CreatedReplacedRelationships 19 | { 20 | get { return createdReplacedRelationships; } 21 | set { createdReplacedRelationships = value; } 22 | } 23 | 24 | public ADTOperationsResult() 25 | { 26 | createdReplacedTwins = new Dictionary(); 27 | createdReplacedRelationships = new Dictionary(); 28 | } 29 | 30 | public void AddCreatedReplacedTwin(BasicDigitalTwin twin) 31 | { 32 | if (twin != null) 33 | CreatedReplacedTwins.Add(twin.Id, twin); 34 | } 35 | 36 | public void AddCreatedReplacedRelationship(BasicRelationship rel) 37 | { 38 | if (rel != null) 39 | CreatedReplacedRelationships.Add(rel.Id, rel); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/aas-services-support/ADT Support/Clients/AzureDigitalTwinsHttpClient.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using System.Net.Http; 4 | 5 | namespace AAS.API.Services.ADT 6 | { 7 | public class AzureDigitalTwinsHttpClient : IAzureDigitalTwinsHttpClient 8 | { 9 | public HttpClient Client { get; set; } 10 | 11 | 12 | public AzureDigitalTwinsHttpClient(HttpClient client) 13 | { 14 | Client = client; 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/aas-services-support/ADT Support/Clients/DigitalTwinsClientFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Azure.Core.Pipeline; 3 | using Azure.DigitalTwins.Core; 4 | using Azure.Identity; 5 | using Microsoft.Extensions.Configuration; 6 | 7 | namespace AAS.API.Services.ADT 8 | { 9 | public interface DigitalTwinsClientFactory 10 | { 11 | public DigitalTwinsClient CreateClient(); 12 | } 13 | 14 | public class StdDigitalTwinsClientFactory : DigitalTwinsClientFactory 15 | { 16 | private IConfiguration _config; 17 | private readonly IAzureDigitalTwinsHttpClient _httpClient; 18 | 19 | public StdDigitalTwinsClientFactory(IConfiguration config, IAzureDigitalTwinsHttpClient httpClient) 20 | { 21 | _config = config; 22 | _httpClient = httpClient; 23 | } 24 | 25 | public DigitalTwinsClient CreateClient() 26 | { 27 | var credentials = new DefaultAzureCredential(); 28 | DigitalTwinsClient client = new DigitalTwinsClient(new Uri(_config["ADT_SERVICE_URL"]), 29 | credentials, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(_httpClient.Client) }); 30 | 31 | return client; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/aas-services-support/ADT Support/Clients/IAzureDigitalTwinsHttpClient.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | 3 | namespace AAS.API.Services.ADT 4 | { 5 | public interface IAzureDigitalTwinsHttpClient 6 | { 7 | public HttpClient Client { get; set; } 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # Asset Administration Shell - Tools for Azure services 2 | 3 | The following tools are provided to manage the lifecycle of the AAS Digital twin graph: 4 | 5 | | Tool | Description | 6 | | --- | --- | 7 | | [AASX Command line](aasx%20command%20line.md) | Imports the contents of an AASX package into an Azure Digital Twin instance | 8 | 9 | -------------------------------------------------------------------------------- /tools/aas-model-generator/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | using Microsoft.DigitalWorkplace.DigitalTwins.Models.Generator; 3 | 4 | Console.WriteLine("Hello, World!"); 5 | 6 | //... 7 | var currentDir = Directory.GetCurrentDirectory(); 8 | var jsonDir = "C:\\Dev\\git\\JMayrbaeurl\\opendigitaltwins-aas\\Ontology"; 9 | var options = new ModelGeneratorOptions 10 | { 11 | OutputDirectory = Path.Combine(currentDir, "..", "..", "..", "Generated"), 12 | Namespace = "Generator.Tests.Generated", 13 | JsonModelsDirectory = jsonDir 14 | }; 15 | 16 | var generator = new ModelGenerator(options); 17 | await generator.GenerateClassesAsync(); -------------------------------------------------------------------------------- /tools/aas-model-generator/aas-model-generator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | aas_model_generator 7 | enable 8 | enable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tools/aasx-cmdline-tests/AASX Package Command line Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | AAS.AASX.CmdLine.Test 6 | 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tools/aasx-cmdline-tests/AbstractTestSupport.cs: -------------------------------------------------------------------------------- 1 | using Azure.Core.Pipeline; 2 | using Azure.DigitalTwins.Core; 3 | using Azure.Identity; 4 | using Microsoft.Extensions.Azure; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Options; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Net.Http; 12 | using System.Text; 13 | 14 | namespace AAS.AASX.CmdLine.Test 15 | { 16 | public abstract class AbstractTestSupport 17 | { 18 | protected IConfiguration configuration; 19 | 20 | protected AbstractTestSupport() 21 | { 22 | configuration = new ConfigurationBuilder().AddJsonFile("appsettings.tests.json").Build(); 23 | } 24 | 25 | protected static void ConfigureBasicServices(IServiceCollection services, string adtInstanceUrl, string tenantId = null) 26 | { 27 | services.Configure(options => options.ADTEndpoint = new Uri(adtInstanceUrl)); 28 | 29 | services.AddAzureClients(builder => 30 | { 31 | builder.AddClient((options, provider) => 32 | { 33 | var appOptions = provider.GetService>(); 34 | 35 | var credentials = new ChainedTokenCredential( 36 | new EnvironmentCredential(), 37 | new ManagedIdentityCredential(), 38 | new AzureCliCredential(new AzureCliCredentialOptions() { TenantId = tenantId }), 39 | new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions() { TenantId = tenantId })); 40 | 41 | DigitalTwinsClient client = new DigitalTwinsClient(appOptions.Value.ADTEndpoint, 42 | credentials, new Azure.DigitalTwins.Core.DigitalTwinsClientOptions { Transport = new HttpClientTransport(new HttpClient()) }); 43 | return client; 44 | }); 45 | 46 | // First use DefaultAzureCredentials and second EnvironmentCredential to enable local docker execution 47 | builder.UseCredential(new ChainedTokenCredential(new DefaultAzureCredential(), new EnvironmentCredential())); 48 | }); 49 | } 50 | } 51 | 52 | public class DigitalTwinsClientOptions 53 | { 54 | public Uri ADTEndpoint { get; set; } 55 | 56 | public string TenantId { get; set; } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tools/aasx-cmdline-tests/appsettings.tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "ADT_SERVICE_URL": "https://aasadtdevjm1.api.weu.digitaltwins.azure.net", 3 | "TENANT_ID": "16b3c013-d300-468d-ac64-7eda0820b6d3" 4 | } -------------------------------------------------------------------------------- /tools/aasx-cmdline/AASUtils.cs: -------------------------------------------------------------------------------- 1 |  2 | using static AdminShellNS.AdminShellV20; 3 | 4 | namespace AAS.AASX.CmdLine 5 | { 6 | public class AASUtils 7 | { 8 | public static string URITOIRI(string idType) 9 | { 10 | if ("URI".Equals(idType)) 11 | return Identification.IRI; 12 | else 13 | return idType; 14 | } 15 | 16 | public static string DescToString(Description desc) 17 | { 18 | if (desc == null) 19 | return default; 20 | else 21 | { 22 | string result = ""; 23 | foreach (var entry in desc.langString) 24 | { 25 | if (result.Length > 0) 26 | result += "\n"; 27 | result += $"{entry.lang},{entry.str}"; 28 | } 29 | 30 | return result; 31 | } 32 | } 33 | 34 | public static string LangStringSetIEC61360ToString(LangStringSetIEC61360 langStrs) 35 | { 36 | if (langStrs == null) 37 | return default; 38 | else 39 | { 40 | string result = ""; 41 | foreach (var entry in langStrs) 42 | { 43 | if (result.Length > 0) 44 | result += "\n"; 45 | result += $"{entry.lang},{entry.str}"; 46 | } 47 | 48 | return result; 49 | } 50 | } 51 | 52 | public static string LangStringSetToString(LangStringSet langStrs) 53 | { 54 | if (langStrs == null) 55 | return default; 56 | else 57 | { 58 | string result = ""; 59 | foreach (var entry in langStrs.langString) 60 | { 61 | if (result.Length > 0) 62 | result += "\n"; 63 | result += $"{entry.lang},{entry.str}"; 64 | } 65 | 66 | return result; 67 | } 68 | } 69 | 70 | public static string StripInvalidTwinIdCharacters(string dtIdProposal) 71 | { 72 | string result = dtIdProposal.Trim(); 73 | 74 | result = result.Replace(" ", ""); 75 | result = result.Replace("/", ""); 76 | 77 | return result; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tools/aasx-cmdline/AASX Package Command line.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | AAS.AASX.CmdLine 7 | aasxcli 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tools/aasx-cmdline/IAASRepo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using static AdminShellNS.AdminShellV20; 6 | 7 | namespace AAS.AASX.CmdLine 8 | { 9 | public interface IAASRepo 10 | { 11 | public Task FindTwinForReference(Reference reference); 12 | 13 | public Task> FindLinkedReferences(); 14 | 15 | public Task> FindReferenceElements(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tools/aasx-cmdline/IAASXInspector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | 6 | namespace AAS.AASX.CmdLine.Inspect 7 | { 8 | public interface IAASXInspector 9 | { 10 | public string ListAllAASXPackageEntries(string packageFilePath); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tools/aasx-cmdline/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "aasx-cmdline ignoreConceptDesc and delete AAS first": { 4 | "commandName": "Project", 5 | "commandLineArgs": "import -f \"C:\\Dev\\ADT\\AAS\\AASX Samples\\01_Festo.aasx\" -u https://aasadtdevjm.api.weu.digitaltwins.azure.net --ignoreConceptDescriptions --DeleteShellsBeforeImport" 6 | }, 7 | "aasx-cmdline full import": { 8 | "commandName": "Project", 9 | "commandLineArgs": "import -f \"C:\\Dev\\ADT\\AAS\\AASX Samples\\01_Festo.aasx\" -u https://aasadtdevjm.api.weu.digitaltwins.azure.net" 10 | }, 11 | "aasx-cmdline list-all": { 12 | "commandName": "Project", 13 | "commandLineArgs": "list-all -f \"C:\\Dev\\ADT\\AAS\\AASX Samples\\01_Festo.aasx\" -u https://aasadtdevjm.api.weu.digitaltwins.azure.net" 14 | }, 15 | "aasx-cmdline import Wittenstein": { 16 | "commandName": "Project", 17 | "commandLineArgs": "import -f \"C:\\Dev\\ADT\\AAS\\AASX Samples\\30_Wittenstein.aasx\" -u https://aasadtjmstaging1.api.weu.digitaltwins.azure.net -t 16b3c013-d300-468d-ac64-7eda0820b6d3" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tools/aasx-cmdline/Resources/Samples/01_Festo Sample/01_Festo in ADT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/tools/aasx-cmdline/Resources/Samples/01_Festo Sample/01_Festo in ADT.jpg -------------------------------------------------------------------------------- /tools/aasx-cmdline/Resources/Samples/07_PhoenixContact_Sample/07_PhoenixContact in ADT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/tools/aasx-cmdline/Resources/Samples/07_PhoenixContact_Sample/07_PhoenixContact in ADT.jpg -------------------------------------------------------------------------------- /tools/aasx-cmdline/Resources/Samples/08_SchneiderElectric_Sample/08_SchneiderElectric in ADT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/tools/aasx-cmdline/Resources/Samples/08_SchneiderElectric_Sample/08_SchneiderElectric in ADT.jpg -------------------------------------------------------------------------------- /tools/aasx-cmdline/Resources/Samples/15_Siemens/15_Siemens in ADT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JMayrbaeurl/opendigitaltwins-aas-azureservices/acbdd4df0915d1127b411ac6b31522282894256a/tools/aasx-cmdline/Resources/Samples/15_Siemens/15_Siemens in ADT.jpg -------------------------------------------------------------------------------- /tools/aasx-cmdline/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning", 5 | "Microsoft": "Warning", 6 | "AAS.AASX": "Information" 7 | }, 8 | "Debug": { 9 | "LogLevel": { 10 | "Default": "Information", 11 | "AAS.AASX": "Trace" 12 | } 13 | } 14 | } 15 | } --------------------------------------------------------------------------------