From 56a04afd4a393928bf9ffe39788ed3dcae3987b1 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 7 Jun 2024 10:12:13 +0200 Subject: [PATCH] Freezor/remove code based on meeting (#264) ### Removed - **Removed all references to OPC UA** (@Freezor) - Removed files: - `AasEntityBuilder.cs` - `AasNodeManager.cs` - `AasUaEntities.cs` - `AasUaEntities.cs.bak` - `AasUaEntityFileType.cs` - `AasUaNodeHelper.cs` - `AasUaUtils.cs` - `AasxUaServerOptions.cs` - `DataChangeMonitoredItem.cs` - `MonitoredItemQueue.cs` - `MonitoredNode.cs` - `Opc.Ua.SampleClient.Config.xml` - `SampleNodeManager.cs` - `SampleServer.SampleModel.cs` - `SampleServer.UserAuthentication.cs` - **Paths**: `src/AasxServerStandardBib/` - **Removed unused and incomplete attribute class** (@Freezor) - Removed file: - `src/AasxServerStandardBib/` - **Removed EnergyModel references (demo showcase)** (@Freezor) - Removed files: - `EnergyModel.cs` - `EnergyModel_SourceSystem_Azure.cs` - `PrefEnergyModel10.cs` - **Path**: `src/AasxServerStandardBib/` - **Removed remaining references to GrapeVineLogger** (@Freezor) - Removed file: - `GrapevineLoggerConsumers.cs` - **Path**: `src/AasxServerStandardBib/` - **Removed I40Message Broker (test implementation)** (@Freezor) - Removed file: - `I40Message.cs` - **Path**: `src/AasxServerStandardBib/` - **Removed MQTT Client/Server (not fully implemented)** (@Freezor) - Removed files: - `MqttClient.cs` - `MqttServer.cs` - **Path**: `src/AasxServerStandardBib/` - **Removed other unused files** (@Freezor) - `MultiTupleDictionary.cs` - `NodeStateCollection.cs` - `Program.cs` - **Path**: `src/AasxServerStandardBib/` --- .gitignore | 106 +- CHANGELOG.md | 60 +- CONTRIBUTING.md | 23 +- src/.gitignore | 1 - src/AasCore.Aas3_0/AasCore.Aas3_0.csproj | 44 +- src/AasCore.Aas3_0/copying.cs | 26 +- src/AasCore.Aas3_0/types.cs | 4 +- src/AasSecurity/AasSecurity.csproj | 22 +- .../AasSecurityAuthenticationHandler.cs | 48 - .../AasSecurityAuthenticationOptions.cs | 8 - .../AasSecurityAuthorizationHandler.cs | 178 - src/AasSecurity/ISecurityService.cs | 3 - src/AasSecurity/SecurityService.cs | 313 +- .../AasxCsharpLibrary.csproj | 98 +- src/AasxCsharpLibrary/AdminShellPackageEnv.cs | 196 +- .../Extensions/ExtendConceptDescription.cs | 75 +- .../Extensions/ExtendEntity.cs | 14 +- .../Extensions/ExtendIReferable.cs | 64 +- .../Extensions/ExtendISubmodelElement.cs | 261 +- .../IAasxOnlineConnection.cs | 2 +- src/AasxServer.sln | 19 +- .../AasxServerAspNetCore.csproj | 50 +- src/AasxServerAspNetCore/Startup.cs | 6 +- src/AasxServerBlazor/AasxServerBlazor.csproj | 146 +- src/AasxServerBlazor/BlazorServerStarter.cs | 2 +- .../Configuration/DependencyRegistry.cs | 1 - .../Configuration/ServerConfiguration.cs | 3 - src/AasxServerBlazor/Pages/Pcf2.razor | 22 +- .../Properties/launchSettings.json | 32 + src/AasxServerBlazor/Shared/MainLayout.razor | 30 +- src/AasxServerBlazor/Startup.cs | 4 +- src/AasxServerStandardBib/AasEntityBuilder.cs | 823 ----- src/AasxServerStandardBib/AasNodeManager.cs | 426 --- src/AasxServerStandardBib/AasUaEntities.cs | 1984 ----------- .../AasUaEntities.cs.bak | 1668 --------- .../AasUaEntityFileType.cs | 391 --- src/AasxServerStandardBib/AasUaNodeHelper.cs | 133 - src/AasxServerStandardBib/AasUaUtils.cs | 173 - .../AasxHttpContextHelper.cs | 685 ++-- src/AasxServerStandardBib/AasxRestServer.cs | 886 ++--- .../AasxServerStandardBib.csproj | 109 +- .../AasxUaServerOptions.cs | 104 - src/AasxServerStandardBib/AttributeClasses.cs | 61 - src/AasxServerStandardBib/Credentials.cs | 10 +- .../DataChangeMonitoredItem.cs | 826 ----- src/AasxServerStandardBib/EnergyModel.cs | 881 ----- .../EnergyModel_SourceSystem_Azure.cs | 26 - .../Exceptions/InvalidIdShortPathException.cs | 9 +- .../GrapevineLoggerConsumers.cs | 91 - src/AasxServerStandardBib/I40Message.cs | 266 -- .../MonitoredItemQueue.cs | 386 --- src/AasxServerStandardBib/MonitoredNode.cs | 382 --- src/AasxServerStandardBib/MqttClient.cs | 101 - src/AasxServerStandardBib/MqttServer.cs | 34 - .../MultiTupleDictionary.cs | 75 - .../NodeStateCollection.cs | 627 ---- .../Opc.Ua.SampleClient.Config.xml | 99 - .../Opc.Ua.SampleServer.Config.xml | 221 -- .../PrefEnergyModel10.cs | 13 - src/AasxServerStandardBib/Program.cs | 691 +--- .../SampleNodeManager.cs | 3015 ----------------- .../SampleServer.SampleModel.cs | 36 - .../SampleServer.UserAuthentication.cs | 179 - src/AasxServerStandardBib/SampleServer.cs | 209 -- src/AasxServerStandardBib/SecurityClient.cs | 436 ++- .../AdminShellPackageEnvironmentService.cs | 86 +- .../Services/IdShortPathParserService.cs | 9 +- .../Services/MetamodelVerificationService.cs | 23 +- .../Services/SubmodelService.cs | 35 +- src/AasxServerStandardBib/TimeSeries.cs | 282 +- src/AasxServerStandardBib/UASampleClient.cs | 230 -- src/AasxServerStandardBib/entityFW.cs | 230 +- src/AasxServerStandardBib/i40Language.cs | 2161 ------------ .../DataTransferObjects.csproj | 22 +- src/ExampleClient/ExampleClient.csproj | 26 +- .../ConceptDescriptionRepositoryAPIApi.cs | 123 +- .../IO.Swagger.Lib.V3.csproj | 62 +- .../Models/BaseOperationResult.cs | 31 +- src/IO.Swagger.Lib.V3/Models/Message.cs | 81 +- src/IO.Swagger.Lib.V3/Models/Result.cs | 37 +- .../ValueMappers/ResponseValueTransformer.cs | 33 +- .../Attributes/ValidateModelStateAttribute.cs | 4 +- .../AssetAdministrationShellRegistryAPIApi.cs | 257 +- .../Filters/BasePathFilter.cs | 4 +- .../GeneratePathParamsValidationFilter.cs | 19 +- .../AasDescriptorRequestFormatter.cs | 3 +- .../AasDescriptorResponseFormatter.cs | 20 +- .../IO.Swagger.Registry.Lib.V3.csproj | 62 +- .../IAasDescriptorPaginationService.cs | 2 +- .../Interfaces/IAasRegistryService.cs | 2 +- .../Interfaces/IRegistryInitializerService.cs | 2 +- .../Models/AasDescriptorPagedResult.cs | 2 +- .../AssetAdministrationShellDescriptor.cs | 41 +- .../Models/Descriptor.cs | 15 +- .../Models/Endpoint.cs | 21 +- .../Models/Message.cs | 44 +- .../Models/ProtocolInformation.cs | 39 +- .../ProtocolInformationSecurityAttributes.cs | 41 +- .../Models/Result.cs | 18 +- .../Models/SubmodelDescriptor.cs | 35 +- .../DescriptorDeserializeImplementation.cs | 1010 +++--- .../Serializers/DescriptorDeserializer.cs | 20 +- .../Serializers/DescriptorSerializer.cs | 81 +- .../AasDescriptorPaginationService.cs | 4 +- .../Services/AasRegistryService.cs | 17 +- .../Services/RegistryInitializerService.cs | 293 +- src/IO.Swagger.Registry.Lib.V3/Startup.cs | 17 +- .../wwwroot/web.config | 15 +- src/es6numberserializer/NumberCachedPowers.cs | 174 +- src/es6numberserializer/NumberDToA.cs | 284 +- src/es6numberserializer/NumberDiyFp.cs | 14 +- src/es6numberserializer/NumberDoubleHelper.cs | 13 +- src/es6numberserializer/NumberFastDToA.cs | 91 +- .../NumberFastDToABuilder.cs | 32 +- src/es6numberserializer/NumberToJson.cs | 4 +- .../es6numberserializer.csproj | 10 +- 116 files changed, 4037 insertions(+), 20061 deletions(-) delete mode 100644 src/.gitignore delete mode 100644 src/AasSecurity/AasSecurityAuthenticationHandler.cs delete mode 100644 src/AasSecurity/AasSecurityAuthenticationOptions.cs delete mode 100644 src/AasSecurity/AasSecurityAuthorizationHandler.cs create mode 100644 src/AasxServerBlazor/Properties/launchSettings.json delete mode 100644 src/AasxServerStandardBib/AasEntityBuilder.cs delete mode 100644 src/AasxServerStandardBib/AasNodeManager.cs delete mode 100644 src/AasxServerStandardBib/AasUaEntities.cs delete mode 100644 src/AasxServerStandardBib/AasUaEntities.cs.bak delete mode 100644 src/AasxServerStandardBib/AasUaEntityFileType.cs delete mode 100644 src/AasxServerStandardBib/AasUaNodeHelper.cs delete mode 100644 src/AasxServerStandardBib/AasUaUtils.cs delete mode 100644 src/AasxServerStandardBib/AasxUaServerOptions.cs delete mode 100644 src/AasxServerStandardBib/AttributeClasses.cs delete mode 100644 src/AasxServerStandardBib/DataChangeMonitoredItem.cs delete mode 100644 src/AasxServerStandardBib/EnergyModel.cs delete mode 100644 src/AasxServerStandardBib/EnergyModel_SourceSystem_Azure.cs delete mode 100644 src/AasxServerStandardBib/GrapevineLoggerConsumers.cs delete mode 100644 src/AasxServerStandardBib/I40Message.cs delete mode 100644 src/AasxServerStandardBib/MonitoredItemQueue.cs delete mode 100644 src/AasxServerStandardBib/MonitoredNode.cs delete mode 100644 src/AasxServerStandardBib/MqttClient.cs delete mode 100644 src/AasxServerStandardBib/MqttServer.cs delete mode 100644 src/AasxServerStandardBib/MultiTupleDictionary.cs delete mode 100644 src/AasxServerStandardBib/NodeStateCollection.cs delete mode 100644 src/AasxServerStandardBib/Opc.Ua.SampleClient.Config.xml delete mode 100644 src/AasxServerStandardBib/Opc.Ua.SampleServer.Config.xml delete mode 100644 src/AasxServerStandardBib/PrefEnergyModel10.cs delete mode 100644 src/AasxServerStandardBib/SampleNodeManager.cs delete mode 100644 src/AasxServerStandardBib/SampleServer.SampleModel.cs delete mode 100644 src/AasxServerStandardBib/SampleServer.UserAuthentication.cs delete mode 100644 src/AasxServerStandardBib/SampleServer.cs delete mode 100644 src/AasxServerStandardBib/UASampleClient.cs delete mode 100644 src/AasxServerStandardBib/i40Language.cs diff --git a/.gitignore b/.gitignore index 0d8799969..2991f7e4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## +## Ignore Visual Studio temporary files, build results, and files generated by popular Visual Studio add-ons. ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore -# Artefacts +# Artefacts and build directories artefacts/ out/ +artifacts/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ # User-specific files *.rsuser @@ -13,8 +16,6 @@ out/ *.user *.userosscache *.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results @@ -26,17 +27,9 @@ x64/ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -# Visual Studio 2015/2017 cache/options directory +# Visual Studio cache/options directory .vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results @@ -58,7 +51,6 @@ BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json -artifacts/ # StyleCop StyleCopReport.xml @@ -174,25 +166,18 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted +# Microsoft Azure Web App publish settings PublishScripts/ # NuGet Packages *.nupkg -# The packages folder can be ignored because of Package Restore **/[Pp]ackages/* -# except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files + +# NuGet v3's project.json files *.nuget.props *.nuget.targets @@ -212,9 +197,7 @@ _pkginfo.txt *.appx # Visual Studio cache files -# files ending in .cache can be ignored *.[Cc]ache -# but keep track of directories ending in .cache !?*.[Cc]ache/ # Others @@ -229,19 +212,12 @@ ClientBin/ orleans.codegen.cs # Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ +# *.snk # RIA/Silverlight projects Generated_Code/ -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) +# Backup & report files from project upgrades _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML @@ -277,7 +253,7 @@ node_modules/ # Visual Studio 6 workspace options file *.opt -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +# Visual Studio 6 auto-generated workspace file *.vbw # Visual Studio LightSwitch build output @@ -306,7 +282,7 @@ paket-files/ __pycache__/ *.pyc -# Cake - Uncomment if you are using it +# Cake # tools/** # !tools/packages.config @@ -342,50 +318,10 @@ ASALocalRun/ # BeatPulse healthcheck temp database healthchecksdb -/Grapevine/Client/PathParams.cs -/Grapevine/Client/QueryString.cs -/Grapevine/Client/RestClient.cs -/Grapevine/Client/RestRequest.cs -/Grapevine/Client/RestResponse.cs -/Grapevine/Exceptions/Client/ClientStateException.cs -/Grapevine/Exceptions/Server/DynamicValueNotFoundException.cs -/Grapevine/Exceptions/Server/InvalidRouteMethodException.cs -/Grapevine/Exceptions/Server/NotFoundException.cs -/Grapevine/Exceptions/Server/ServerStateException.cs -/Grapevine/Exceptions/Server/UnableToStartHostException.cs -/Grapevine/Exceptions/Server/UnableToStopHostException.cs -/Grapevine/Grapevine.csproj -/Grapevine/Interfaces/Server/HttpContext.cs -/Grapevine/Interfaces/Server/HttpRequest.cs -/Grapevine/Interfaces/Server/HttpResponse.cs -/Grapevine/Interfaces/Server/IHttpListener.cs -/Grapevine/Interfaces/Server/IHttpListenerContext.cs -/Grapevine/Interfaces/Shared/IGrapevineLogger.cs -/Grapevine/Server/Attributes/RestResource.cs -/Grapevine/Server/Attributes/RestRoute.cs -/Grapevine/Server/HttpResponseExtensions.cs -/Grapevine/Server/PublicFolder.cs -/Grapevine/Server/RestCluster.cs -/Grapevine/Server/RestServer.cs -/Grapevine/Server/Route.cs -/Grapevine/Server/RouteScanner.cs -/Grapevine/Server/Router.cs -/Grapevine/Server/ServerSettings.cs -/Grapevine/Shared/ContentType.cs -/Grapevine/Shared/DynamicProperties.cs -/Grapevine/Shared/HttpMethod.cs -/Grapevine/Shared/HttpStatusCode.cs -/Grapevine/Shared/InternalExtensions.cs -/Grapevine/Shared/Loggers/ConsoleLogger.cs -/Grapevine/Shared/Loggers/InMemoryLogger.cs -/Grapevine/Shared/Loggers/LoggerExtensions.cs -/Grapevine/Shared/Loggers/NullLogger.cs -/Grapevine/Shared/NameValueCollectionExtensions.cs -/Grapevine/Shared/ParamParser.cs -/Grapevine/Shared/PortFinder.cs -/Grapevine/Shared/StreamExtensions.cs -/Grapevine/Shared/UriScheme.cs -/Grapevine/Shared/UriSchemeExtensions.cs + +# Grapevine content +Grapevine/* + +# Custom ignores /src/AasxServerStandardBib/AdminShell.cs.old -/src/AasxServerBlazor/temp.aasx -/src/AasxServerBlazor/Properties/launchSettings.json +/src/AasxServerBlazor/temp.aasx \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c924a240..928eca614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Renamed Program1.cs to BlazorServerStarter for better readability and to avoid misunderstandings, as there already is a Program class. (@Freezor) +- Cleaned BlazorServerStarter in general to have an easier understanding on the process (@Freezor) +- Extracted dependency registration into DependencyRegistry.cs and server configuration into ServerConfiguration.cs from Startup.cs (@Freezor) +- Refactored ServerConfiguration.cs into smaller parts and applying Clean code and SOLID principles. (@Freezor) + ### Updated -- Microsoft.IdentityModel.Tokens from **6.13.1** to **7.5.0** because of a package vulnerability. +- Microsoft.IdentityModel.Tokens from **6.13.1** to **6.35.0** because of a package vulnerability. (@Freezor) -### Changed +### Removed -- Renamed Program1.cs to BlazorServerStarter for better readability and to avoid misunderstandings, as there already is a Program class. -- Cleaned BlazorServerStarter in general to have an easier understanding on the process -- Extracted dependency registration into DependencyRegistry.cs and server configuration into ServerConfiguration.cs from Startup.cs -- Refactored ServerConfiguration.cs into smaller parts and applying Clean code and SOLID principles. +- **Removed all references to OPC UA** (@Freezor) + - Removed files: + - `AasEntityBuilder.cs` + - `AasNodeManager.cs` + - `AasUaEntities.cs` + - `AasUaEntities.cs.bak` + - `AasUaEntityFileType.cs` + - `AasUaNodeHelper.cs` + - `AasUaUtils.cs` + - `AasxUaServerOptions.cs` + - `DataChangeMonitoredItem.cs` + - `MonitoredItemQueue.cs` + - `MonitoredNode.cs` + - `Opc.Ua.SampleClient.Config.xml` + - `SampleNodeManager.cs` + - `SampleServer.SampleModel.cs` + - `SampleServer.UserAuthentication.cs` + - **Paths**: `src/AasxServerStandardBib/` +- **Removed unused and incomplete attribute class** (@Freezor) + - Removed file: + - `src/AasxServerStandardBib/` +- **Removed EnergyModel references (demo showcase)** (@Freezor) + - Removed files: + - `EnergyModel.cs` + - `EnergyModel_SourceSystem_Azure.cs` + - `PrefEnergyModel10.cs` + - **Path**: `src/AasxServerStandardBib/` +- **Removed remaining references to GrapeVineLogger** (@Freezor) + - Removed file: + - `GrapevineLoggerConsumers.cs` + - **Path**: `src/AasxServerStandardBib/` +- **Removed I40Message Broker (test implementation)** (@Freezor) + - Removed file: + - `I40Message.cs` + - **Path**: `src/AasxServerStandardBib/` +- **Removed MQTT Client/Server (not fully implemented)** (@Freezor) + - Removed files: + - `MqttClient.cs` + - `MqttServer.cs` + - **Path**: `src/AasxServerStandardBib/` +- **Removed other unused files** (@Freezor) + - `MultiTupleDictionary.cs` + - `NodeStateCollection.cs` + - `Program.cs` + - **Path**: `src/AasxServerStandardBib/` ## [Released] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e75b42b2..84eada019 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,11 +61,24 @@ Run the checks with: ### Branching -**If you are part of the `Eclipse AASX Package Explorer and Server`GitHub organization:** -Create a branch prefixed with your GitHub username using dashes to describe the change (e.g., `mristin/Add-a-shiny-new-feature-B`). - -**Otherwise:** If you are not a member of the organization, you need to fork the repository and create your feature branch on the fork. -See the [GitHub documentation about forking][github-fork]. +#### For `Eclipse AASX Package Explorer and Server` Committers + +1. **Integration Branch:** + - Create a new integration branch in the main repository (e.g., "integration/freezor"). + - All your unique PRs will be collected there and, upon consultation, merged to the 'main' branch. + - Keep this branch up to date with the main regularly and resolve merge conflicts. +2. **Feature Branch:** + - Create a branch prefixed with your GitHub username using dashes to describe the change (e.g., `mristin/Add-a-shiny-new-feature-B`). + - This branch can reside in the repository or your own fork. + - When naming branches, refer to [Tilburg Science Hub](https://tilburgsciencehub.com/topics/automation/version-control/advanced-git/naming-git-branches/). + +#### For Community Contributors + +1. **Forking Repository:** + - If you are not a member of the organization, you need to fork the repository and create your feature branch on the fork. + - See the [GitHub documentation about forking][github-fork]. +2. **Naming Convention:** + - Ensure good naming practices for your branches. Refer to [Tilburg Science Hub](https://tilburgsciencehub.com/topics/automation/version-control/advanced-git/naming-git-branches/) for guidelines on branch names. [github-fork]: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index 23053de09..000000000 --- a/src/.gitignore +++ /dev/null @@ -1 +0,0 @@ -packages/ diff --git a/src/AasCore.Aas3_0/AasCore.Aas3_0.csproj b/src/AasCore.Aas3_0/AasCore.Aas3_0.csproj index 96a86a8a9..5fa15e746 100644 --- a/src/AasCore.Aas3_0/AasCore.Aas3_0.csproj +++ b/src/AasCore.Aas3_0/AasCore.Aas3_0.csproj @@ -1,25 +1,25 @@  - - net6.0 - enable - Debug;Release;DebugSlow - AnyCPU - 8 + + net6.0 + enable + Debug;Release;DebugSlow + AnyCPU + 8 - AasCore.Aas3_0 - 1.0.0-rc1 - Marko Ristin - - An SDK for manipulating, verifying and de/serializing Asset Administration Shells. - - https://github.com/aas-core-works/aas-core3.0-csharp.git - git - Copyright (c) 2023 Marko Ristin - https://raw.githubusercontent.com/aas-core-works/aas-core3.0-csharp/main/LICENSE - https://github.com/aas-core-works/aas-core3.0-csharp - aas;asset administration shell;iiot;industry internet of things;industrie 4.0;i4.0 - - - - + AasCore.Aas3_0 + 1.0.0-rc1 + Marko Ristin + + An SDK for manipulating, verifying and de/serializing Asset Administration Shells. + + https://github.com/aas-core-works/aas-core3.0-csharp.git + git + Copyright (c) 2023 Marko Ristin + https://raw.githubusercontent.com/aas-core-works/aas-core3.0-csharp/main/LICENSE + https://github.com/aas-core-works/aas-core3.0-csharp + aas;asset administration shell;iiot;industry internet of things;industrie 4.0;i4.0 + + + + diff --git a/src/AasCore.Aas3_0/copying.cs b/src/AasCore.Aas3_0/copying.cs index 9cfb5dca6..63bba7527 100644 --- a/src/AasCore.Aas3_0/copying.cs +++ b/src/AasCore.Aas3_0/copying.cs @@ -3,8 +3,8 @@ * Do NOT edit or append. */ -using System.Collections.Generic; // can't alias -using Aas = AasCore.Aas3_0; // renamed +using System.Collections.Generic; // can't alias +using Aas = AasCore.Aas3_0; // renamed namespace AasCore.Aas3_0 { @@ -31,7 +31,7 @@ public static class Copying /// type to cast the result to public static T Shallow(T that) where T : Aas.IClass { - return (T)ShallowCopierInstance.Transform(that); + return (T) ShallowCopierInstance.Transform(that); } /// @@ -41,7 +41,7 @@ public static T Shallow(T that) where T : Aas.IClass /// type to cast the result to public static T Deep(T that) where T : Aas.IClass { - return (T)DeepCopierInstance.Transform(that); + return (T) DeepCopierInstance.Transform(that); } /// Dispatch the making of shallow copies. @@ -572,14 +572,14 @@ Aas.IDataSpecificationIec61360 that that.Value, that.LevelType); } - } // internal class ShallowCopier + } // internal class ShallowCopier /// Dispatch the making of deep copies. internal class DeepCopier : Visitation.AbstractTransformer { public override Aas.IClass TransformExtension( - Aas.IExtension that - ) + Aas.IExtension that + ) { List? theSupplementalSemanticIds = null; if (that.SupplementalSemanticIds != null) @@ -1269,7 +1269,7 @@ Aas.IProperty that foreach (var item in that.EmbeddedDataSpecifications) { if (item.DataSpecification != null && item.DataSpecificationContent != null) - theEmbeddedDataSpecifications.Add(Deep(item)); + theEmbeddedDataSpecifications.Add(Deep(item)); } } @@ -2462,11 +2462,13 @@ Aas.IEmbeddedDataSpecification that { theDataSpecification = Deep(that.DataSpecification); } + IDataSpecificationContent? theDataSpecificationContent = null; if (that.DataSpecificationContent != null) { theDataSpecificationContent = Deep(that.DataSpecificationContent); } + return new Aas.EmbeddedDataSpecification(theDataSpecification, theDataSpecificationContent); } @@ -2592,11 +2594,11 @@ Aas.IDataSpecificationIec61360 that : null ); } - } // internal class DeepCopier - } // public static class Copying -} // namespace AasCore.Aas3_0 + } // internal class DeepCopier + } // public static class Copying +} // namespace AasCore.Aas3_0 /* * This code has been automatically generated by aas-core-codegen. * Do NOT edit or append. - */ + */ \ No newline at end of file diff --git a/src/AasCore.Aas3_0/types.cs b/src/AasCore.Aas3_0/types.cs index 3bf4f228b..d766d6f15 100644 --- a/src/AasCore.Aas3_0/types.cs +++ b/src/AasCore.Aas3_0/types.cs @@ -8774,7 +8774,7 @@ public interface IBasicEventElement : IEventElement /// the proprietary specification for the message broker. /// /// - /// For different message infrastructure, e.g., OPC UA or MQTT or AMQP, this + /// For different message infrastructure, e.g., MQTT or AMQP, this /// proprietary specification could be standardized by having respective Submodels. /// public IReference? MessageBroker { get; set; } @@ -8962,7 +8962,7 @@ public class BasicEventElement : IBasicEventElement /// the proprietary specification for the message broker. /// /// - /// For different message infrastructure, e.g., OPC UA or MQTT or AMQP, this + /// For different message infrastructure, e.g., MQTT or AMQP, this /// proprietary specification could be standardized by having respective Submodels. /// public IReference? MessageBroker { get; set; } diff --git a/src/AasSecurity/AasSecurity.csproj b/src/AasSecurity/AasSecurity.csproj index c14647253..718a33cd1 100644 --- a/src/AasSecurity/AasSecurity.csproj +++ b/src/AasSecurity/AasSecurity.csproj @@ -1,17 +1,17 @@ - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - - + + + - - - + + + diff --git a/src/AasSecurity/AasSecurityAuthenticationHandler.cs b/src/AasSecurity/AasSecurityAuthenticationHandler.cs deleted file mode 100644 index e87fded76..000000000 --- a/src/AasSecurity/AasSecurityAuthenticationHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -using AasxServerStandardBib.Logging; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System.Security.Claims; -using System.Text.Encodings.Web; - -namespace AasSecurity -{ - public class AasSecurityAuthenticationHandler : AuthenticationHandler - { - private static ILogger _logger = ApplicationLogging.CreateLogger("AasSecurityAuthenticationHandler"); - private readonly ISecurityService _securityService; - - public AasSecurityAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, ISecurityService securityService) : base(options, logger, encoder, clock) - { - _securityService = securityService; - } - - - protected override async Task HandleAuthenticateAsync() - { - _logger.LogDebug("Authenticating the request."); - if (!GlobalSecurityVariables.WithAuthentication) - { - _logger.LogDebug("Server is configured without security. Therefore, skipping authentication."); - var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(Enumerable.Empty(), Scheme.Name)); - var authenticationTicket = new AuthenticationTicket(claimsPrincipal, Scheme.Name); - - return AuthenticateResult.Success(authenticationTicket); - } - - var httpMethod = Request.Method; - var httpRoute = Request.Path.Value; - var context = Request.HttpContext; - var ticket = _securityService.AuthenticateRequest(context, httpRoute, httpMethod, Scheme.Name); - if (ticket == null) - { - return AuthenticateResult.Fail(new Exception($"Request cannot be authenticated.")); - } - - _logger.LogInformation($"Request is successfully authenticated."); - return AuthenticateResult.Success(ticket); - - } - - } -} diff --git a/src/AasSecurity/AasSecurityAuthenticationOptions.cs b/src/AasSecurity/AasSecurityAuthenticationOptions.cs deleted file mode 100644 index 5eb74f7f0..000000000 --- a/src/AasSecurity/AasSecurityAuthenticationOptions.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Microsoft.AspNetCore.Authentication; - -namespace AasSecurity -{ - public class AasSecurityAuthenticationOptions : AuthenticationSchemeOptions - { - } -} diff --git a/src/AasSecurity/AasSecurityAuthorizationHandler.cs b/src/AasSecurity/AasSecurityAuthorizationHandler.cs deleted file mode 100644 index a80a79650..000000000 --- a/src/AasSecurity/AasSecurityAuthorizationHandler.cs +++ /dev/null @@ -1,178 +0,0 @@ -using AasSecurity.Models; -using AasxServer; -using AasxServerStandardBib.Logging; -using AdminShellNS.Models; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.Extensions.Logging; -using Microsoft.IdentityModel.Tokens; -using System.Security.Claims; - -namespace AasSecurity -{ - public class AasSecurityAuthorizationHandler : AuthorizationHandler - { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly ISecurityService _securityService; - private static ILogger _logger = ApplicationLogging.CreateLogger("SecurityHandler"); - - public AasSecurityAuthorizationHandler(IHttpContextAccessor httpContextAccessor, ISecurityService securityService) - { - _httpContextAccessor = httpContextAccessor; - _securityService = securityService; - } - - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SecurityRequirement requirement, object resource) - { - _logger.LogDebug("Authorizing the request"); - if (!GlobalSecurityVariables.WithAuthentication) - { - _logger.LogDebug("Server is configured without security. Therefore, skipping authorization."); - context.Succeed(requirement); - return Task.CompletedTask; - } - //Get User Claims - var httpRequest = _httpContextAccessor.HttpContext!.Request; - string httpRoute = httpRequest.Path.Value!; - bool isAuthorized = false; - string getPolicy = ""; - string policy = ""; - string accessRole = ""; string idShortPath = null; string error = null; - AccessRights neededRights = AccessRights.READ; - var claims = context.User; - if (claims != null) - { - accessRole = claims.FindFirst(ClaimTypes.Role)!.Value; - string right = claims.FindFirst("NeededRights")!.Value; - if (claims.HasClaim(c => c.Type.Equals("IdShortPath"))) - { - idShortPath = claims.FindFirst("IdShortPath")!.Value; - } - Enum.TryParse(right, out neededRights); - var policyclaim = claims.FindFirst("Policy"); - if (policyclaim != null) - { - policy = policyclaim.Value; - } - } - if (!string.IsNullOrEmpty(idShortPath)) - { - var parentSubmodel = resource as ISubmodel; - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy, idShortPath, null, parentSubmodel); - } - else if (resource is ISubmodel submodel) - { - var httpOperation = httpRequest.Method; - if (httpOperation.ToLower().Equals("head")) - { - policy = null; - } - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy, submodel.IdShort!, "submodel", submodel, policy); - } - else if (resource is IAssetAdministrationShell aas) - { - var header = _httpContextAccessor.HttpContext.Request.Headers["IsGetAllPackagesApi"]; - if (!header.IsNullOrEmpty() && header.Any()) - { - bool isGetAllPackagesApi = bool.Parse(header.First()); - if (isGetAllPackagesApi) - { - httpRoute = "/packages"; - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy); - } - } - else if (httpRoute.Contains("/packages/")) - { - //This if AASX File Server IF call, hence check the security for API Operation - bool isAuthorisedApi = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy); - //Check the security for the resource aas - bool isAuthorisedAas = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy, "", "aas", aas); - isAuthorized = isAuthorisedApi && isAuthorisedAas; - } - else - { - //The request is solely for AAS - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy, "", "aas", aas); - } - - } - else if (resource is List || resource is IConceptDescription) - { - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy); - } - else if (resource is List packages) - { - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy); - } - else if (resource is string resourceString && resourceString.IsNullOrEmpty()) - { - isAuthorized = _securityService.AuthorizeRequest(accessRole, httpRoute, neededRights, out error, out _, out getPolicy); - } - - if (isAuthorized) - { - _logger.LogInformation("Request authorized successfully."); - - if (getPolicy != "") - { - _httpContextAccessor.HttpContext.Response.Headers.Append("policy", getPolicy); - _httpContextAccessor.HttpContext.Response.Headers.Append("policyRequestedResource", httpRequest.Path.Value); - } - - context.Succeed(requirement); - } - else - { - _logger.LogInformation("Request could not be authorized successfully."); - - //Checking the redirect configuration - if (httpRoute.Contains("/packages/")) - { - if (!string.IsNullOrEmpty(Program.redirectServer) && (accessRole == "isNotAuthenticated" || accessRole == null)) - { - _logger.LogDebug("Request can be redirected."); - System.Collections.Specialized.NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty); - string originalRequest = _httpContextAccessor.HttpContext.Request.GetDisplayUrl(); - queryString.Add("OriginalRequest", originalRequest); - _logger.LogDebug("Redirect OriginalRequset: " + originalRequest); - string response = Program.redirectServer + "?" + "authType=" + Program.authType + "&" + queryString; - _logger.LogDebug("Redirect Response: " + response + "\n"); - - CreateRedirectResponse(response); - context.Fail(); - - } - else - context.Fail(new AuthorizationFailureReason(this, error)); - } - else - context.Fail(new AuthorizationFailureReason(this, error)); - } - - return Task.CompletedTask; - } - - private void CreateRedirectResponse(string responseUrl) - { - AllowCORS(); - - var context = _httpContextAccessor.HttpContext; - if (context != null) - { - context.Response.Headers.Append("redirectInfo", responseUrl); - context.Response.Redirect(responseUrl); - context.Response.StatusCode = StatusCodes.Status307TemporaryRedirect; - } - } - - private void AllowCORS() - { - var context = _httpContextAccessor.HttpContext; - context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); - context.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); - context.Response.Headers.Add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); - context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); - } - } -} diff --git a/src/AasSecurity/ISecurityService.cs b/src/AasSecurity/ISecurityService.cs index 99af580bc..db388bbf7 100644 --- a/src/AasSecurity/ISecurityService.cs +++ b/src/AasSecurity/ISecurityService.cs @@ -1,12 +1,9 @@ using AasSecurity.Models; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; namespace AasSecurity { public interface ISecurityService { - AuthenticationTicket AuthenticateRequest(HttpContext context, string route, string httpOperation, string authenticationSchemeName = null); bool AuthorizeRequest(string accessRole, string httpRoute, AccessRights neededRights, out string error, out bool withAllow, out string getPolicy, string objPath = null, string aasResourceType = null, IClass aasResource = null, string policy = null); diff --git a/src/AasSecurity/SecurityService.cs b/src/AasSecurity/SecurityService.cs index 5742df99f..616d4b824 100644 --- a/src/AasSecurity/SecurityService.cs +++ b/src/AasSecurity/SecurityService.cs @@ -3,17 +3,13 @@ using AasxServerStandardBib.Logging; using Extensions; using Jose; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using System.Collections.Specialized; using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; -using System.Web; namespace AasSecurity { @@ -21,50 +17,6 @@ public class SecurityService : ISecurityService { private static ILogger _logger = ApplicationLogging.CreateLogger("SecurityService"); - public AuthenticationTicket AuthenticateRequest(HttpContext context, string route, string httpOperation, string authenticationSchemeName) - { - if (!GlobalSecurityVariables.WithAuthentication) - { - return null; - } - - //Retrieve security related query strings from the request - NameValueCollection queries = HttpUtility.ParseQueryString(context.Request.QueryString.ToString()); - - //Retrieve headers from the request - NameValueCollection headers = new NameValueCollection(); - foreach (var header in context.Request.Headers) - { - headers.Add(header.Key, header.Value.FirstOrDefault()); - if (header.Key == "FORCE-POLICY") - { - Program.withPolicy = !(header.Value.FirstOrDefault() == "OFF"); - _logger.LogDebug("FORCE-POLICY " + header.Value.FirstOrDefault()); - } - } - - var accessRole = GetAccessRole(queries, headers, out string policy, out string policyRequestedResource); - if (accessRole == null) - { - _logger.LogDebug($"Access Role found null. Hence setting the access role as isNotAuthenticated."); - accessRole = "isNotAuthenticated"; - } - - _logger.LogInformation($"Access role in authentication: {accessRole}, policy: {policy}, policyRequestedResource: {policyRequestedResource}"); - var aasSecurityContext = new AasSecurityContext(accessRole, route, httpOperation); - //Create claims - var claims = new List - { - new Claim(ClaimTypes.Role, aasSecurityContext.AccessRole), - new Claim("NeededRights", aasSecurityContext.NeededRights.ToString()), - new Claim("Policy", policy) - }; - - var identity = new ClaimsIdentity(claims, authenticationSchemeName); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); - return new AuthenticationTicket(principal, authenticationSchemeName); - } - private string? GetAccessRole(NameValueCollection queries, NameValueCollection headers, out string policy, out string policyRequestedResource) { _logger.LogDebug("Getting the access rights."); @@ -107,6 +59,7 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout } } } + //Domain foreach (var securityRight in securityRights) { @@ -116,13 +69,15 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout if (user.Contains('@')) { string[] split = user.Split('@'); - domain = split[1]; + domain = split[ 1 ]; } + if (domain != null && domain.Equals(securityRight.Name)) { accessRole = securityRight.Role; return accessRole; } + if (user == securityRight.Name) { accessRole = securityRight.Role; @@ -160,6 +115,7 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout user = email.ToLower(); } } + var serverNameClaim = jwtSecurityToken.Claims.Where(c => c.Type.Equals("serverName")); if (!serverNameClaim.IsNullOrEmpty()) { @@ -213,10 +169,8 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout user = userName.ToLower(); } } - } } - } catch (Exception ex) { @@ -229,7 +183,8 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout return ""; } - private AccessRights? ParseBearerToken(NameValueCollection queries, NameValueCollection headers, ref string? bearerToken, ref bool error, ref string? user, ref string? accessRights) + private AccessRights? ParseBearerToken(NameValueCollection queries, NameValueCollection headers, ref string? bearerToken, ref bool error, ref string? user, + ref string? accessRights) { //Check the token in header foreach (string key in headers.Keys) @@ -237,64 +192,68 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout switch (key.ToLower()) { case "authorization": + { + var token = headers[ key ]; + if (token != null) { - var token = headers[key]; - if (token != null) + string[] split = token.Split(new Char[] {' ', '\t'}); + if (split[ 0 ].ToLower().Equals("bearer")) { - string[] split = token.Split(new Char[] { ' ', '\t' }); - if (split[0].ToLower().Equals("bearer")) - { - _logger.LogDebug($"Received bearer token {split[1]}"); - bearerToken = split[1]; - } - else if (split[0].ToLower().Equals("basic") && bearerToken == null) + _logger.LogDebug($"Received bearer token {split[ 1 ]}"); + bearerToken = split[ 1 ]; + } + else if (split[ 0 ].ToLower().Equals("basic") && bearerToken == null) + { + try { - try + if (Program.secretStringAPI != null) { - if (Program.secretStringAPI != null) - { - var credentialBytes = Convert.FromBase64String(split[1]); - var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); - string u = credentials[0]; - string p = credentials[1]; - Console.WriteLine("Received username+password http header = " + u + " : " + p); + var credentialBytes = Convert.FromBase64String(split[ 1 ]); + var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] {':'}, 2); + string u = credentials[ 0 ]; + string p = credentials[ 1 ]; + Console.WriteLine("Received username+password http header = " + u + " : " + p); - if (u == "secret") + if (u == "secret") + { + accessRights = "READ"; { - accessRights = "READ"; - { - if (p == Program.secretStringAPI) - accessRights = "CREATE"; - } - _logger.LogDebug("accessrights " + accessRights); - AccessRights output = (AccessRights)Enum.Parse(typeof(AccessRights), accessRights); - return output; + if (p == Program.secretStringAPI) + accessRights = "CREATE"; } + _logger.LogDebug("accessrights " + accessRights); + AccessRights output = (AccessRights) Enum.Parse(typeof(AccessRights), accessRights); + return output; } + } - string username = CheckUserPW(split[1]); - if (username != null) - { - user = username; - Console.WriteLine("Received username+password http header = " + user); - } + string username = CheckUserPW(split[ 1 ]); + if (username != null) + { + user = username; + Console.WriteLine("Received username+password http header = " + user); } - catch { } + } + catch + { } } - break; } + + break; + } case "email": + { + var token = headers[ key ]; + if (token != null) { - var token = headers[key]; - if (token != null) - { - _logger.LogDebug($"Received email token from header: {token}"); - user = token; - error = false; - } - break; + _logger.LogDebug($"Received email token from header: {token}"); + user = token; + error = false; } + + break; + } } } @@ -304,61 +263,67 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout switch (key.ToLower()) { case "s": + { + string secretQuery = queries[ "s" ]!; + if (!secretQuery.IsNullOrEmpty()) { - string secretQuery = queries["s"]!; - if (!secretQuery.IsNullOrEmpty()) + _logger.LogDebug($"Received token of type s: {secretQuery}"); + if (Program.secretStringAPI != null) { - _logger.LogDebug($"Received token of type s: {secretQuery}"); - if (Program.secretStringAPI != null) + if (secretQuery.Equals(Program.secretStringAPI)) { - if (secretQuery.Equals(Program.secretStringAPI)) - { - return AccessRights.CREATE; // Set AccessRole to create - } + return AccessRights.CREATE; // Set AccessRole to create } } - break; } + + break; + } case "bearer": + { + var token = queries[ key ]; + if (token != null) { - var token = queries[key]; - if (token != null) - { - _logger.LogDebug($"Received token of type bear {token}"); - bearerToken = token; - } - break; + _logger.LogDebug($"Received token of type bear {token}"); + bearerToken = token; } + + break; + } case "email": + { + var token = queries[ key ]; + if (token != null) { - var token = queries[key]; - if (token != null) - { - _logger.LogDebug($"Received token of type email {token}"); - user = token; - error = false; - } - break; + _logger.LogDebug($"Received token of type email {token}"); + user = token; + error = false; } + + break; + } case "_up": + { + var token = queries[ key ]; + if (token != null) { - var token = queries[key]; - if (token != null) + _logger.LogDebug($"Received token of type username-password {token}"); + try { - _logger.LogDebug($"Received token of type username-password {token}"); - try + string username = CheckUserPW(token); + if (username != null) { - string username = CheckUserPW(token); - if (username != null) - { - user = username; - _logger.LogDebug("Received username+password query string = " + user); - } + user = username; + _logger.LogDebug("Received username+password query string = " + user); } - catch { } } - break; + catch + { + } } + + break; + } } } @@ -368,9 +333,9 @@ public AuthenticationTicket AuthenticateRequest(HttpContext context, string rout private string CheckUserPW(string userPW64) { var credentialBytes = Convert.FromBase64String(userPW64); - var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); - string username = credentials[0]; - string password = credentials[1]; + var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] {':'}, 2); + string username = credentials[ 0 ]; + string password = credentials[ 1 ]; var found = GlobalSecurityVariables.SecurityUsernamePassword.TryGetValue(username, out string storedPassword); if (found) @@ -385,8 +350,8 @@ private string CheckUserPW(string userPW64) } public bool AuthorizeRequest(string accessRole, string httpRoute, AccessRights neededRights, - out string error, out bool withAllow, out string getPolicy, string objPath = null, string aasResourceType = null, - IClass aasResource = null, string policy = null) + out string error, out bool withAllow, out string getPolicy, string objPath = null, string aasResourceType = null, + IClass aasResource = null, string policy = null) { return CheckAccessRights(accessRole, httpRoute, neededRights, out error, out withAllow, out getPolicy, objPath, aasResourceType, aasResource, policy: policy); } @@ -399,7 +364,8 @@ private static bool CheckAccessRights(string currentRole, string operation, Acce objPath, aasResourceType, aasResource, testOnly, policy); } - private static bool CheckAccessRightsWithAllow(string currentRole, string operation, AccessRights neededRights, out string error, out bool withAllow, out string getPolicy, string objPath = "", string aasResourceType = null, IClass aasResource = null, bool testOnly = false, string policy = null) + private static bool CheckAccessRightsWithAllow(string currentRole, string operation, AccessRights neededRights, out string error, out bool withAllow, out string getPolicy, + string objPath = "", string aasResourceType = null, IClass aasResource = null, bool testOnly = false, string policy = null) { error = "Access not allowed"; withAllow = false; @@ -407,14 +373,14 @@ private static bool CheckAccessRightsWithAllow(string currentRole, string operat if (Program.secretStringAPI != null && currentRole == "CREATE") { - return true; + return true; } else { // TODO (jtikekar, 2023-09-04): uncomment if (CheckAccessLevelWithError( - out error, currentRole, operation, neededRights, out withAllow, out getPolicy, - objPath, aasResourceType, aasResource, policy)) + out error, currentRole, operation, neededRights, out withAllow, out getPolicy, + objPath, aasResourceType, aasResource, policy)) return true; } @@ -428,7 +394,8 @@ private static bool CheckAccessRightsWithAllow(string currentRole, string operat return false; } - private static bool CheckAccessLevelWithError(out string error, string currentRole, string operation, AccessRights neededRights, out bool withAllow, out string getPolicy, string objPath, string aasResourceType, IClass aasResource, string policy = null) + private static bool CheckAccessLevelWithError(out string error, string currentRole, string operation, AccessRights neededRights, out bool withAllow, out string getPolicy, + string objPath, string aasResourceType, IClass aasResource, string policy = null) { withAllow = false; getPolicy = ""; @@ -439,11 +406,11 @@ private static bool CheckAccessLevelWithError(out string error, string currentRo } _logger.LogDebug("checkAccessLevel: " + - " currentRole = " + currentRole + - " operation = " + operation + - " neededRights = " + neededRights + - " objPath = " + objPath - ); + " currentRole = " + currentRole + + " operation = " + operation + + " neededRights = " + neededRights + + " objPath = " + objPath + ); if (aasResource == null) { @@ -530,6 +497,7 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out break; } } + if (maxCount == null || duration == null || actualCount == null || actualTime == null) return false; int d = 0; @@ -537,6 +505,7 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out { return false; } + DateTime dt = new DateTime(); if (actualTime.Value != null && actualTime.Value != "") { @@ -549,29 +518,36 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out actualTime.Value = null; } } - catch { } + catch + { + } } + if (actualTime.Value == null || actualTime.Value == "") { actualTime.Value = DateTime.UtcNow.ToString(); actualCount.Value = null; } + if (actualCount.Value == null || actualCount.Value == "") { actualCount.Value = "0"; } + int ac = 0; if (!int.TryParse(actualCount.Value, out ac)) { Program.signalNewData(0); return false; } + int mc = 0; if (!int.TryParse(maxCount.Value, out mc)) { Program.signalNewData(0); return false; } + ac++; actualCount.Value = ac.ToString(); if (ac <= mc) @@ -580,6 +556,7 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out return true; } } + break; case "policy": pPolicy = sme as Property; @@ -613,7 +590,9 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out } } } - catch { } + catch + { + } } if (policy == null || policy.Contains(getPolicy)) @@ -622,12 +601,12 @@ private static bool CheckPolicy(out string error, SecurityRole securityRole, out } - // Program.signalNewData(0); return false; } - private static bool CheckAccessLevelForOperation(string currentRole, string operation, string aasResourceType, IClass aasResource, AccessRights neededRights, string objPath, out bool withAllow, out string getPolicy, out string error, string policy = null) + private static bool CheckAccessLevelForOperation(string currentRole, string operation, string aasResourceType, IClass aasResource, AccessRights neededRights, + string objPath, out bool withAllow, out string getPolicy, out string error, string policy = null) { error = ""; withAllow = false; @@ -648,7 +627,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper { if (securityRole.SemanticId == "*" || (submodel.SemanticId != null && submodel.SemanticId.Keys != null && submodel.SemanticId.Keys.Count != 0)) { - if (securityRole.SemanticId == "*" || (securityRole.SemanticId.ToLower() == submodel.SemanticId?.Keys?[0].Value.ToLower())) + if (securityRole.SemanticId == "*" || (securityRole.SemanticId.ToLower() == submodel.SemanticId?.Keys?[ 0 ].Value.ToLower())) { if (securityRole.Kind == KindOfPermissionEnum.Allow) { @@ -659,6 +638,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper deepestAllowRole = securityRole; } } + if (securityRole.Kind == KindOfPermissionEnum.Deny) { if (deepestDeny == "") @@ -669,6 +649,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper } } } + if ((securityRole.ObjectType == "sm" || securityRole.ObjectType == "submodelElement") && securityRole.Submodel == aasResource && securityRole.Permission == neededRights) { @@ -679,6 +660,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper if (securityRole.ObjectPath == objPath.Substring(0, securityRole.ObjectPath.Length)) deepestDeny = securityRole.ObjectPath; } + if (securityRole.ObjectPath.Length >= objPath.Length) // deny in tree below { if (objPath == securityRole.ObjectPath.Substring(0, objPath.Length)) @@ -688,6 +670,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper } } } + if (securityRole.Kind == KindOfPermissionEnum.Allow) { if (objPath.Length >= securityRole.ObjectPath.Length) // allow in tree above @@ -708,6 +691,7 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper error = "ALLOW not defined"; return false; } + if (deepestDeny.Length > deepestAllow.Length) { error = "DENY " + deepestDeny; @@ -718,7 +702,8 @@ private static bool CheckAccessLevelForOperation(string currentRole, string oper //return true; } - private static bool CheckAccessLevelEmptyObjPath(string currentRole, string operation, string aasResourceType, IClass aasResource, AccessRights neededRights, out string error) + private static bool CheckAccessLevelEmptyObjPath(string currentRole, string operation, string aasResourceType, IClass aasResource, AccessRights neededRights, + out string error) { //error = string.Empty; if (GlobalSecurityVariables.SecurityRoles != null) @@ -729,16 +714,18 @@ private static bool CheckAccessLevelEmptyObjPath(string currentRole, string oper { var aas = aasResource as IAssetAdministrationShell; //if (aasResourceType != null && securityRole.ObjectReference == aasResource && securityRole.Permission == neededRights) - if (aasResourceType != null && (aas.EqualsAas((IAssetAdministrationShell)securityRole.ObjectReference) || securityRole.AAS == "*") && securityRole.Permission == neededRights) + if (aasResourceType != null && (aas.EqualsAas((IAssetAdministrationShell) securityRole.ObjectReference) || securityRole.AAS == "*") && + securityRole.Permission == neededRights) { if ((securityRole.Condition == "" && securityRole.Name == currentRole) || - (securityRole.Condition == "not" && securityRole.Name != currentRole)) + (securityRole.Condition == "not" && securityRole.Name != currentRole)) { if (securityRole.Kind == KindOfPermissionEnum.Allow) { error = ""; return true; } + if (securityRole.Kind == KindOfPermissionEnum.Deny) { error = "DENY AAS " + (aasResource as AssetAdministrationShell).Id; @@ -762,6 +749,7 @@ private static bool CheckAccessLevelEmptyObjPath(string currentRole, string oper //} } } + error = "ALLOW not defined"; return false; } @@ -778,11 +766,11 @@ private static bool MatchApiOperation(string apiOperation, string operation) { for (int i = 0; i < apiOpSplit.Length; i++) { - if (apiOpSplit[i].Equals(opSplit[i])) + if (apiOpSplit[ i ].Equals(opSplit[ i ])) { match = true; } - else if (apiOpSplit[i].StartsWith("{")) + else if (apiOpSplit[ i ].StartsWith("{")) { continue; } @@ -790,7 +778,6 @@ private static bool MatchApiOperation(string apiOperation, string operation) { match = false; } - } return match; @@ -836,6 +823,7 @@ private static bool CheckUsage(out string error, SecurityRole securityRole) break; } } + if (maxCount == null || duration == null || actualCount == null || actualTime == null) return false; int d = 0; @@ -843,6 +831,7 @@ private static bool CheckUsage(out string error, SecurityRole securityRole) { return false; } + DateTime dt = new DateTime(); if (actualTime.Value != null && actualTime.Value != "") { @@ -855,29 +844,36 @@ private static bool CheckUsage(out string error, SecurityRole securityRole) actualTime.Value = null; } } - catch { } + catch + { + } } + if (actualTime.Value == null || actualTime.Value == "") { actualTime.Value = DateTime.UtcNow.ToString(); actualCount.Value = null; } + if (actualCount.Value == null || actualCount.Value == "") { actualCount.Value = "0"; } + int ac = 0; if (!int.TryParse(actualCount.Value, out ac)) { Program.signalNewData(0); return false; } + int mc = 0; if (!int.TryParse(maxCount.Value, out mc)) { Program.signalNewData(0); return false; } + ac++; actualCount.Value = ac.ToString(); if (ac <= mc) @@ -886,6 +882,7 @@ private static bool CheckUsage(out string error, SecurityRole securityRole) return true; } } + break; } } @@ -931,4 +928,4 @@ public string GetSecurityRules() return rules; } } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/AasxCsharpLibrary.csproj b/src/AasxCsharpLibrary/AasxCsharpLibrary.csproj index 1e76f10a7..9ea97f7af 100644 --- a/src/AasxCsharpLibrary/AasxCsharpLibrary.csproj +++ b/src/AasxCsharpLibrary/AasxCsharpLibrary.csproj @@ -1,51 +1,51 @@  - - net6.0 - Library - AdminShellNS - false - - - false - - - TRACE;UseAasxCompatibilityModels - - - false - - - - - - - PreserveNewest - - - - - Designer - PreserveNewest - - - Designer - PreserveNewest - - - Designer - PreserveNewest - - - - - - - - - - - - - - + + net6.0 + Library + AdminShellNS + false + + + false + + + TRACE;UseAasxCompatibilityModels + + + false + + + + + + + PreserveNewest + + + + + Designer + PreserveNewest + + + Designer + PreserveNewest + + + Designer + PreserveNewest + + + + + + + + + + + + + + diff --git a/src/AasxCsharpLibrary/AdminShellPackageEnv.cs b/src/AasxCsharpLibrary/AdminShellPackageEnv.cs index 79ce10f71..6f28f5771 100644 --- a/src/AasxCsharpLibrary/AdminShellPackageEnv.cs +++ b/src/AasxCsharpLibrary/AdminShellPackageEnv.cs @@ -8,7 +8,6 @@ This source code may use other Open Source software components (see LICENSE.txt) */ - using Extensions; using Newtonsoft.Json; // using ScottPlot.Drawing.Colormaps; @@ -34,9 +33,18 @@ public class AdminShellPackageSupplementaryFile /*: IReferable*/ { public delegate byte[] SourceGetByteChunk(); - public enum LocationType { InPackage, AddPending, DeletePending } + public enum LocationType + { + InPackage, + AddPending, + DeletePending + } - public enum SpecialHandlingType { None, EmbedAsThumbnail } + public enum SpecialHandlingType + { + None, + EmbedAsThumbnail + } public readonly Uri Uri = null; @@ -66,7 +74,6 @@ public string GetElementName() { return "File"; } - } public class ListOfAasSupplementaryFile : List @@ -86,7 +93,6 @@ public AdminShellPackageSupplementaryFile FindByUri(string path) /// public static class AdminShellSerializationHelper { - public static string TryReadXmlFirstElementNamespaceURI(Stream s) { string res = null; @@ -109,6 +115,7 @@ public static string TryReadXmlFirstElementNamespaceURI(Stream s) break; } } + xr.Close(); } catch (Exception ex) @@ -223,7 +230,7 @@ public static T DeserializeFromJSON(string data) where T : IReferable var node = System.Text.Json.Nodes.JsonNode.Parse(data); var rf = Jsonization.Deserialize.IReferableFrom(node); - return (T)rf; + return (T) rf; //} } @@ -268,7 +275,9 @@ public class AdminShellPackageEnv : IDisposable private bool write = false; - public AdminShellPackageEnv() { } + public AdminShellPackageEnv() + { + } public bool getWrite() { @@ -299,10 +308,7 @@ public AdminShellPackageEnv(string fn, bool indirectLoadSave = false, bool loadX public bool IsOpen { - get - { - return _openPackage != null; - } + get { return _openPackage != null; } } public void SetFilename(string fileName) @@ -312,18 +318,12 @@ public void SetFilename(string fileName) public string Filename { - get - { - return _fn; - } + get { return _fn; } } public AasCore.Aas3_0.Environment AasEnv { - get - { - return _aasEnv; - } + get { return _aasEnv; } } private static AasCore.Aas3_0.Environment LoadXml(string fn) @@ -413,6 +413,7 @@ private static (AasCore.Aas3_0.Environment, Package, String) LoadPackageAasx(str { originPart = package.GetPart(absoluteURI); } + break; } @@ -429,6 +430,7 @@ private static (AasCore.Aas3_0.Environment, Package, String) LoadPackageAasx(str { originPart = package.GetPart(absoluteURI); } + break; } } @@ -447,6 +449,7 @@ private static (AasCore.Aas3_0.Environment, Package, String) LoadPackageAasx(str { specPart = package.GetPart(absoluteURI); } + break; } @@ -461,6 +464,7 @@ private static (AasCore.Aas3_0.Environment, Package, String) LoadPackageAasx(str { specPart = package.GetPart(absoluteURI); } + break; } } @@ -552,43 +556,42 @@ public void Load(string fn, bool indirectLoadSave = false, bool loadXml = false) switch (extension) { case ".xml": - { - _aasEnv = LoadXml(fn); - break; - } + { + _aasEnv = LoadXml(fn); + break; + } case ".json": - { - _aasEnv = LoadJson(fn); - break; - } + { + _aasEnv = LoadJson(fn); + break; + } case ".aasx": + { + var fnToLoad = fn; + _tempFn = null; + if (indirectLoadSave) { - var fnToLoad = fn; - _tempFn = null; - if (indirectLoadSave) + try { - try - { - _tempFn = System.IO.Path.GetTempFileName().Replace(".tmp", ".aasx"); - System.IO.File.Copy(fn, _tempFn); - fnToLoad = _tempFn; - - } - catch (Exception ex) - { - throw new Exception( - $"While copying AASX {fn} for indirect load to {fnToLoad} " + - $"at {AdminShellUtil.ShortLocation(ex)} gave: {ex.Message}"); - } + _tempFn = System.IO.Path.GetTempFileName().Replace(".tmp", ".aasx"); + System.IO.File.Copy(fn, _tempFn); + fnToLoad = _tempFn; + } + catch (Exception ex) + { + throw new Exception( + $"While copying AASX {fn} for indirect load to {fnToLoad} " + + $"at {AdminShellUtil.ShortLocation(ex)} gave: {ex.Message}"); } + } - // load package AASX - (_aasEnv, _openPackage, _envXml) = LoadPackageAasx(fn, fnToLoad, loadXml); + // load package AASX + (_aasEnv, _openPackage, _envXml) = LoadPackageAasx(fn, fnToLoad, loadXml); - //Assign default thumbnail path - AssignDefaultThumbnailPath(); - break; - } + //Assign default thumbnail path + AssignDefaultThumbnailPath(); + break; + } default: throw new Exception( $"Does not know how to handle the extension {extension} of the file: {fn}"); @@ -614,14 +617,16 @@ private void AssignDefaultThumbnailPath() { thumbPart = _openPackage.GetPart(absoluteURI); } + thumbUri = x.TargetUri; break; } + if (thumbUri != null && !string.IsNullOrEmpty(thumbUri.OriginalString)) { if (_aasEnv.AssetAdministrationShells.Count > 0) { - _aasEnv.AssetAdministrationShells[0].AssetInformation.DefaultThumbnail = new Resource(thumbUri.OriginalString); + _aasEnv.AssetAdministrationShells[ 0 ].AssetInformation.DefaultThumbnail = new Resource(thumbUri.OriginalString); } } } @@ -632,7 +637,6 @@ public void SetTempFn(string fn) { _tempFn = System.IO.Path.GetTempFileName().Replace(".tmp", ".aasx"); System.IO.File.Copy(fn, _tempFn); - } catch (Exception ex) { @@ -666,7 +670,12 @@ public void LoadFromAasEnvString(string content) } } - public enum SerializationFormat { None, Xml, Json }; + public enum SerializationFormat + { + None, + Xml, + Json + }; //public static XmlSerializerNamespaces GetXmlDefaultNamespaces() //{ @@ -679,7 +688,7 @@ public enum SerializationFormat { None, Xml, Json }; //} public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat prefFmt = SerializationFormat.None, - MemoryStream useMemoryStream = null, bool saveOnlyCopy = false) + MemoryStream useMemoryStream = null, bool saveOnlyCopy = false) { if (fn.ToLower().EndsWith(".xml")) { @@ -689,7 +698,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre try { Stream s = (useMemoryStream != null) - ? (Stream)useMemoryStream + ? (Stream) useMemoryStream : System.IO.File.Open(fn, FileMode.Create, FileAccess.Write); try @@ -723,6 +732,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre string.Format("While writing AAS {0} at {1} gave: {2}", fn, AdminShellUtil.ShortLocation(ex), ex.Message))); } + return true; } @@ -734,7 +744,8 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre _fn = fn; try { - Stream s = (useMemoryStream != null) ? (Stream)useMemoryStream + Stream s = (useMemoryStream != null) + ? (Stream) useMemoryStream : System.IO.File.Open(fn, FileMode.Create, FileAccess.Write); try @@ -785,6 +796,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre string.Format("While writing AAS {0} at {1} gave: {2}", fn, AdminShellUtil.ShortLocation(ex), ex.Message))); } + return true; } @@ -820,6 +832,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { LogInternally.That.SilentlyIgnoredError(ex); } + _openPackage = null; } @@ -836,6 +849,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre (_tempFn != null) ? _tempFn : fn, (writeFreshly) ? FileMode.Create : FileMode.OpenOrCreate); } + _fn = fn; // get the origin from the package @@ -852,6 +866,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { originPart = package.GetPart(absoluteURI); } + //delete old type, because its not according to spec or something //then replace with the current type package.DeleteRelationship(x.Id); @@ -861,6 +876,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre originPart = null; break; } + xs = package.GetRelationshipsByType("http://admin-shell.io/aasx/relationships/aasx-origin"); foreach (var x in xs) if (x.SourceUri.ToString() == "/") @@ -871,8 +887,10 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { originPart = package.GetPart(absoluteURI); } + break; } + if (originPart == null) { // create, as not existing @@ -884,6 +902,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre var bytes = System.Text.Encoding.ASCII.GetBytes("Intentionally empty."); s.Write(bytes, 0, bytes.Length); } + package.CreateRelationship( originPart.Uri, TargetMode.Internal, "http://admin-shell.io/aasx/relationships/aasx-origin"); @@ -902,6 +921,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { specPart = package.GetPart(absoluteURI); } + //delete old type, because its not according to spec or something //then replace with the current type originPart.DeleteRelationship(x.Id); @@ -912,6 +932,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre specRel = null; break; } + xs = originPart.GetRelationshipsByType("http://admin-shell.io/aasx/relationships/aas-spec"); foreach (var x in xs) { @@ -933,8 +954,8 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre specPart.Uri.ToString()).ToLower().Trim(); var ext = System.IO.Path.GetExtension(specPart.Uri.ToString()).ToLower().Trim(); if ((ext == ".json" && prefFmt == SerializationFormat.Xml) - || (ext == ".xml" && prefFmt == SerializationFormat.Json) - || (name.StartsWith("aasenv-with-no-id"))) + || (ext == ".xml" && prefFmt == SerializationFormat.Json) + || (name.StartsWith("aasenv-with-no-id"))) { // try kill specpart try @@ -946,7 +967,11 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { LogInternally.That.SilentlyIgnoredError(ex); } - finally { specPart = null; specRel = null; } + finally + { + specPart = null; + specRel = null; + } } } @@ -955,7 +980,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre // create, as not existing var frn = "aasenv-with-no-id"; if (_aasEnv.AssetAdministrationShells.Count > 0) - frn = _aasEnv.AssetAdministrationShells[0].GetFriendlyName() ?? frn; + frn = _aasEnv.AssetAdministrationShells[ 0 ].GetFriendlyName() ?? frn; var aas_spec_fn = "/aasx/#/#.aas"; if (prefFmt == SerializationFormat.Json) aas_spec_fn += ".json"; @@ -1013,7 +1038,6 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre //Need to check/test in detail, with thumbnails as well if (specPart != null) { - xs = specPart.GetRelationshipsByType("http://www.admin-shell.io/aasx/relationships/aas-suppl"); if (xs != null) { @@ -1026,6 +1050,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { filePart = package.GetPart(absoluteURI); } + //delete old type, because its not according to spec or something //then replace with the current type specPart.DeleteRelationship(x.Id); @@ -1088,9 +1113,8 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre // normal file? if (psfAdd.SpecialHandling == AdminShellPackageSupplementaryFile.SpecialHandlingType.None || psfAdd.SpecialHandling == - AdminShellPackageSupplementaryFile.SpecialHandlingType.EmbedAsThumbnail) + AdminShellPackageSupplementaryFile.SpecialHandlingType.EmbedAsThumbnail) { - // try find an existing part for that file .. PackagePart filePart = null; if (psfAdd.SpecialHandling == AdminShellPackageSupplementaryFile.SpecialHandlingType.None) @@ -1106,9 +1130,11 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { filePart = package.GetPart(absoluteURI); } + break; } } + if (psfAdd.SpecialHandling == AdminShellPackageSupplementaryFile.SpecialHandlingType.EmbedAsThumbnail) { @@ -1123,6 +1149,7 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { filePart = package.GetPart(absoluteURI); } + break; } } @@ -1193,15 +1220,16 @@ public bool SaveAs(string fn, bool writeFreshly = false, SerializationFormat pre { throw (new Exception( string.Format("While write AASX {0} indirectly at {1} gave: {2}", - fn, AdminShellUtil.ShortLocation(ex), ex.Message))); + fn, AdminShellUtil.ShortLocation(ex), ex.Message))); } } catch (Exception ex) { throw (new Exception( string.Format("While write AASX {0} at {1} gave: {2}", - fn, AdminShellUtil.ShortLocation(ex), ex.Message))); + fn, AdminShellUtil.ShortLocation(ex), ex.Message))); } + return true; } @@ -1223,7 +1251,7 @@ public void TemporarilySaveCloseAndReOpenPackage( if (!this.IsOpen) throw (new Exception( string.Format("Could not temporarily close and re-open AASX {0}, because package" + - "not open as expected!", Filename))); + "not open as expected!", Filename))); try { @@ -1241,7 +1269,7 @@ public void TemporarilySaveCloseAndReOpenPackage( { throw (new Exception( string.Format("While temporarily close and re-open AASX {0} at {1} gave: {2}", - Filename, AdminShellUtil.ShortLocation(ex), ex.Message))); + Filename, AdminShellUtil.ShortLocation(ex), ex.Message))); } finally { @@ -1268,6 +1296,7 @@ public void BackupInDir(string backupDir, int maxFiles) var rnd = new Random(); BackupIndex = rnd.Next(maxFiles); } + var ndx = BackupIndex % maxFiles; BackupIndex += 1; @@ -1350,6 +1379,7 @@ public bool IsLocalFile(string uriString) public static bool withDb = false; public static bool withDbFiles = false; public static string dataPath = ""; + public static void setGlobalOptions(bool _withDb, bool _withDbFiles, string _dataPath) { withDb = _withDb; @@ -1400,8 +1430,8 @@ public async Task ReplaceSupplementaryFileInPackageAsync(string sourceUri, strin if (!string.IsNullOrEmpty(sourceUri)) { _openPackage.DeletePart(new Uri(sourceUri, UriKind.RelativeOrAbsolute)); - } + var targetUri = PackUriHelper.CreatePartUri(new Uri(targetFile, UriKind.RelativeOrAbsolute)); PackagePart packagePart = _openPackage.CreatePart(targetUri, targetContentType); fileContent.Position = 0; @@ -1425,6 +1455,7 @@ public long GetStreamSizeFromPackage(string uriString) { part = _openPackage.GetPart(uri); } + if (part != null) { using (var s = part.GetStream(FileMode.Open)) @@ -1438,6 +1469,7 @@ public long GetStreamSizeFromPackage(string uriString) LogInternally.That.SilentlyIgnoredError(ex); return 0; } + return res; } @@ -1473,9 +1505,11 @@ public Stream GetLocalThumbnailStream(ref Uri thumbUri, bool init = false) { thumbPart = _openPackage.GetPart(absoluteURI); } + thumbUri = x.TargetUri; break; } + if (thumbPart == null) // throw (new Exception("Unable to find AASX thumbnail. Aborting!")); return null; @@ -1519,7 +1553,6 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() // access if (_openPackage != null) { - // get the thumbnail(s) from the package var xs = _openPackage.GetRelationshipsByType( "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"); @@ -1545,12 +1578,14 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() { originPart = _openPackage.GetPart(absoluteURI); } + break; } - if(xs == null) + + if (xs == null) { xs = _openPackage.GetRelationshipsByType( - "http://www.admin-shell.io/aasx/relationships/aasx-origin"); + "http://www.admin-shell.io/aasx/relationships/aasx-origin"); foreach (var x in xs) if (x.SourceUri.ToString() == "/") { @@ -1560,6 +1595,7 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() { originPart = _openPackage.GetPart(absoluteURI); } + break; } } @@ -1577,9 +1613,11 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() { specPart = _openPackage.GetPart(absoluteURI); } + break; } - if(xs == null) + + if (xs == null) { xs = originPart.GetRelationshipsByType("http://www.admin-shell.io/aasx/relationships/aas-spec"); foreach (var x in xs) @@ -1590,6 +1628,7 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() { specPart = _openPackage.GetPart(absoluteURI); } + break; } } @@ -1604,7 +1643,8 @@ public ListOfAasSupplementaryFile GetListOfSupplementaryFiles() new AdminShellPackageSupplementaryFile( x.TargetUri, location: AdminShellPackageSupplementaryFile.LocationType.InPackage)); } - if(xs == null) + + if (xs == null) { xs = specPart.GetRelationshipsByType("http://www.admin-shell.io/aasx/relationships/aas-suppl"); foreach (var x in xs) @@ -1730,8 +1770,7 @@ public void AddSupplementaryFileToStore(string sourcePath, string targetPath, bo : AdminShellPackageSupplementaryFile.SpecialHandlingType.None), sourceGetBytesDel: sourceGetBytesDel, useMimeType: useMimeType) - ); - + ); } public void DeleteSupplementaryFile(AdminShellPackageSupplementaryFile psf) @@ -1815,15 +1854,15 @@ public void EmbeddAssetInformationThumbnail(IResource defaultThumbnail, Stream f { var sourceUri = defaultThumbnail.Path.Replace(Path.DirectorySeparatorChar, '/'); _openPackage.DeletePart(new Uri(sourceUri, UriKind.RelativeOrAbsolute)); - } + var targetUri = PackUriHelper.CreatePartUri(new Uri(defaultThumbnail.Path, UriKind.RelativeOrAbsolute)); PackagePart packagePart = _openPackage.CreatePart(targetUri, defaultThumbnail.ContentType, compressionOption: CompressionOption.Maximum); _openPackage.CreateRelationship(packagePart.Uri, TargetMode.Internal, - "http://schemas.openxmlformats.org/package/2006/" + - "relationships/metadata/thumbnail"); + "http://schemas.openxmlformats.org/package/2006/" + + "relationships/metadata/thumbnail"); //Write to the part fileContent.Position = 0; @@ -1860,8 +1899,7 @@ public void DeleteAssetInformationThumbnail(IResource defaultThumbnail) { var sourceUri = defaultThumbnail.Path.Replace(Path.DirectorySeparatorChar, '/'); _openPackage.DeletePart(new Uri(sourceUri, UriKind.RelativeOrAbsolute)); - } } } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/Extensions/ExtendConceptDescription.cs b/src/AasxCsharpLibrary/Extensions/ExtendConceptDescription.cs index 9d5515898..875457058 100644 --- a/src/AasxCsharpLibrary/Extensions/ExtendConceptDescription.cs +++ b/src/AasxCsharpLibrary/Extensions/ExtendConceptDescription.cs @@ -12,37 +12,35 @@ public static class ExtendConceptDescription public static string GetDefaultPreferredName(this ConceptDescription conceptDescription, string defaultLang = null) { return "" + - conceptDescription.GetIEC61360()? - .PreferredName?.GetDefaultString(defaultLang); + conceptDescription.GetIEC61360()? + .PreferredName?.GetDefaultString(defaultLang); } public static EmbeddedDataSpecification SetIEC61360Spec(this ConceptDescription conceptDescription, - string[] preferredNames = null, - string shortName = "", - string unit = "", - Reference unitId = null, - string valueFormat = null, - string sourceOfDefinition = null, - string symbol = null, - string dataType = "", - string[] definition = null - ) + string[] preferredNames = null, + string shortName = "", + string unit = "", + Reference unitId = null, + string valueFormat = null, + string sourceOfDefinition = null, + string symbol = null, + string dataType = "", + string[] definition = null + ) { - var eds = new EmbeddedDataSpecification( - new Reference(ReferenceTypes.ExternalReference, - new List { ExtendIDataSpecificationContent.GetKeyForIec61360() }), + var eds = new EmbeddedDataSpecification(new Reference(ReferenceTypes.ExternalReference, new List {ExtendIDataSpecificationContent.GetKeyForIec61360()}), new DataSpecificationIec61360( - ExtendLangStringSet.CreateManyPreferredNamesFromStringArray(preferredNames), - new List { new LangStringShortNameTypeIec61360("EN?", shortName) }, - unit, - unitId, - sourceOfDefinition, - symbol, - Stringification.DataTypeIec61360FromString(dataType), - ExtendLangStringSet.CreateManyDefinitionFromStringArray(definition) - )); - - conceptDescription.EmbeddedDataSpecifications = new List { eds }; + ExtendLangStringSet.CreateManyPreferredNamesFromStringArray(preferredNames), + new List {new LangStringShortNameTypeIec61360("EN?", shortName)}, + unit, + unitId, + sourceOfDefinition, + symbol, + Stringification.DataTypeIec61360FromString(dataType), + ExtendLangStringSet.CreateManyDefinitionFromStringArray(definition) + )); + + conceptDescription.EmbeddedDataSpecifications = new List {eds}; // TODO (MIHO, 2022-12-22): Check, but I think it makes no sense // conceptDescription.IsCaseOf ??= new List(); @@ -79,8 +77,8 @@ public static Tuple ToCaptionInfo(this ConceptDescription concep public static string GetDefaultShortName(this ConceptDescription conceptDescription, string defaultLang = null) { return "" + - conceptDescription.GetIEC61360()? - .ShortName?.GetDefaultString(defaultLang); + conceptDescription.GetIEC61360()? + .ShortName?.GetDefaultString(defaultLang); } public static DataSpecificationIec61360 GetIEC61360(this ConceptDescription conceptDescription) @@ -100,13 +98,16 @@ public static IEnumerable FindAllReferences(this IConceptDescription } #endregion + #region ListOfConceptDescription + public static ConceptDescription AddConceptDescriptionOrReturnExisting(this List conceptDescriptions, ConceptDescription newConceptDescription) { if (newConceptDescription == null) { return null; } + if (conceptDescriptions != null) { var existingCd = conceptDescriptions.Where(c => c.Id == newConceptDescription.Id).First(); @@ -122,6 +123,7 @@ public static ConceptDescription AddConceptDescriptionOrReturnExisting(this List return newConceptDescription; } + #endregion public static void Validate(this ConceptDescription conceptDescription, AasValidationRecordList results) @@ -179,7 +181,9 @@ public static Key GetSingleKey(this ConceptDescription conceptDescription) { return new Key(KeyTypes.ConceptDescription, conceptDescription.Id); } - public static ConceptDescription ConvertFromV10(this ConceptDescription conceptDescription, AasxCompatibilityModels.AdminShellV10.ConceptDescription sourceConceptDescription) + + public static ConceptDescription ConvertFromV10(this ConceptDescription conceptDescription, + AasxCompatibilityModels.AdminShellV10.ConceptDescription sourceConceptDescription) { if (sourceConceptDescription == null) { @@ -202,18 +206,18 @@ public static ConceptDescription ConvertFromV10(this ConceptDescription conceptD if (sourceConceptDescription.administration != null) { - conceptDescription.Administration = new AdministrativeInformation(version: sourceConceptDescription.administration.version, revision: sourceConceptDescription.administration.revision); + conceptDescription.Administration = new AdministrativeInformation(version: sourceConceptDescription.administration.version, + revision: sourceConceptDescription.administration.revision); } if (sourceConceptDescription.IsCaseOf != null && sourceConceptDescription.IsCaseOf.Count != 0) { - foreach (var caseOf in sourceConceptDescription.IsCaseOf) { if (!caseOf.IsEmpty) { conceptDescription.IsCaseOf ??= new List(); - conceptDescription.IsCaseOf.Add(ExtensionsUtil.ConvertReferenceFromV10(caseOf, ReferenceTypes.ModelReference)); + conceptDescription.IsCaseOf.Add(ExtensionsUtil.ConvertReferenceFromV10(caseOf, ReferenceTypes.ModelReference)); } } } @@ -243,13 +247,12 @@ public static ConceptDescription ConvertFromV20(this ConceptDescription cd, Aasx if (srcCD.IsCaseOf != null && srcCD.IsCaseOf.Count != 0) { - foreach (var caseOf in srcCD.IsCaseOf) { if (!caseOf.IsEmpty) { cd.IsCaseOf ??= new List(); - cd.IsCaseOf.Add(ExtensionsUtil.ConvertReferenceFromV20(caseOf, ReferenceTypes.ModelReference)); + cd.IsCaseOf.Add(ExtensionsUtil.ConvertReferenceFromV20(caseOf, ReferenceTypes.ModelReference)); } } } @@ -282,7 +285,7 @@ public static EmbeddedDataSpecification AddEmbeddedDataSpecification(this Concep public static Reference GetCdReference(this ConceptDescription conceptDescription) { var key = new Key(KeyTypes.ConceptDescription, conceptDescription.Id); - return new Reference(ReferenceTypes.ModelReference, new List { key }); + return new Reference(ReferenceTypes.ModelReference, new List {key}); } public static void AddIsCaseOf(this ConceptDescription cd, @@ -293,4 +296,4 @@ public static void AddIsCaseOf(this ConceptDescription cd, cd.IsCaseOf.Add(ico); } } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/Extensions/ExtendEntity.cs b/src/AasxCsharpLibrary/Extensions/ExtendEntity.cs index 4ae66c27e..a1f0e6e83 100644 --- a/src/AasxCsharpLibrary/Extensions/ExtendEntity.cs +++ b/src/AasxCsharpLibrary/Extensions/ExtendEntity.cs @@ -46,6 +46,7 @@ public static object AddChild(this Entity entity, ISubmodelElement childSubmodel } #endregion + public static Entity ConvertFromV20(this Entity entity, AasxCompatibilityModels.AdminShellV20.Entity sourceEntity) { if (sourceEntity == null) @@ -64,6 +65,7 @@ public static Entity ConvertFromV20(this Entity entity, AasxCompatibilityModels. { outputSubmodelElement = outputSubmodelElement.ConvertFromV20(sourceSubmodelElement); } + entity.Statements.Add(outputSubmodelElement); } } @@ -72,11 +74,10 @@ public static Entity ConvertFromV20(this Entity entity, AasxCompatibilityModels. { // TODO (jtikekar, 2023-09-04):jtikekar whether to convert to Global or specific asset id var assetRef = ExtensionsUtil.ConvertReferenceFromV20(sourceEntity.assetRef, ReferenceTypes.ExternalReference); - if (assetRef!=null) + if (assetRef != null) { entity.GlobalAssetId = assetRef.GetAsIdentifier(); - - } + } } return entity; @@ -84,12 +85,11 @@ public static Entity ConvertFromV20(this Entity entity, AasxCompatibilityModels. public static T FindFirstIdShortAs(this IEntity entity, string idShort) where T : ISubmodelElement { - var submodelElements = entity.Statements.Where(sme => (sme != null) && (sme is T) && sme.IdShort.Equals(idShort, StringComparison.OrdinalIgnoreCase)); if (submodelElements.Any()) { - return (T)submodelElements.First(); + return (T) submodelElements.First(); } return default; @@ -99,7 +99,7 @@ public static T CreateSMEForCD( this Entity ent, ConceptDescription conceptDescription, string category = null, string idShort = null, string idxTemplate = null, int maxNum = 999, bool addSme = false, bool isTemplate = false) - where T : ISubmodelElement + where T : ISubmodelElement { if (ent.Statements == null) ent.Statements = new List(); @@ -107,4 +107,4 @@ public static T CreateSMEForCD( conceptDescription, category, idShort, idxTemplate, maxNum, addSme, isTemplate); } } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/Extensions/ExtendIReferable.cs b/src/AasxCsharpLibrary/Extensions/ExtendIReferable.cs index 0e0890f48..9482529c3 100644 --- a/src/AasxCsharpLibrary/Extensions/ExtendIReferable.cs +++ b/src/AasxCsharpLibrary/Extensions/ExtendIReferable.cs @@ -11,8 +11,8 @@ public static class ExtendIReferable #region AasxPackageExplorer public static void RecurseOnReferables(this IReferable referable, - object state, Func, IReferable, bool> lambda, - bool includeThis = false) + object state, Func, IReferable, bool> lambda, + bool includeThis = false) { if (referable is Submodel submodel) { @@ -101,12 +101,14 @@ public static IIdentifiable FindParentFirstIdentifiable(this IReferable referabl return curri; curr = curr.Parent as IReferable; } + return null; } #endregion #region ListOfReferables + public static Reference GetReference(this List referables) { return new Reference(ReferenceTypes.ExternalReference, referables.ToKeyList()); @@ -119,6 +121,7 @@ public static List ToKeyList(this List referables) res.Add(new Key(rf.GetSelfDescription()?.KeyType ?? KeyTypes.GlobalReference, rf.IdShort)); return res; } + #endregion public static string ToIdShortString(this IReferable rf) @@ -141,6 +144,7 @@ public static Reference GetReference(this IReferable referable) else return null; } + public static void Validate(this IReferable referable, AasValidationRecordList results) { referable.BaseValidation(results); @@ -170,19 +174,13 @@ public static void BaseValidation(this IReferable referable, AasValidationRecord results.Add(new AasValidationRecord( AasValidationSeverity.SpecViolation, referable, "Referable: missing idShort", - () => - { - referable.IdShort = "TO_FIX"; - })); + () => { referable.IdShort = "TO_FIX"; })); if (referable.Description != null && (referable.Description.Count < 1)) results.Add(new AasValidationRecord( AasValidationSeverity.SchemaViolation, referable, "Referable: existing description with missing langString", - () => - { - referable.Description = null; - })); + () => { referable.Description = null; })); } /// @@ -278,7 +276,6 @@ public static AasElementSelfDescription GetSelfDescription(this IReferable refer else if (referable is BasicEventElement) { return new AasElementSelfDescription("BasicEventElement", "Evt", - KeyTypes.BasicEventElement, AasSubmodelElements.BasicEventElement); } else if (referable is IDataElement) @@ -297,6 +294,7 @@ public static AasElementSelfDescription GetSelfDescription(this IReferable refer KeyTypes.Referable, null); } } + public static void CollectReferencesByParent(this IReferable referable, List refs) { // access @@ -312,20 +310,21 @@ public static void CollectReferencesByParent(this IReferable referable, List ListOfIReferableFrom( - System.Text.Json.Nodes.JsonNode node) + System.Text.Json.Nodes.JsonNode node) { var res = new List(); if (node == null) @@ -486,6 +484,7 @@ public static List ListOfIReferableFrom( var ir = Jsonization.Deserialize.IReferableFrom(it); res.Add(ir); } + return res; } @@ -572,20 +571,21 @@ public static void MigrateV20QualifiersToExtensions(this IReferable rf) return; // Qualifiers to migrate - var toMigrate = new[] { + var toMigrate = new[] + { "Animate.Args", "Plotting.Args", "TimeSeries.Args", "BOM.Args", "ImageMap.Args" }; List toMove = new List(); foreach (var q in iq.Qualifiers) - foreach (var tm in toMigrate) - if (q?.Type?.Equals(tm, StringComparison.InvariantCultureIgnoreCase) == true) - toMove.Add(q); + foreach (var tm in toMigrate) + if (q?.Type?.Equals(tm, StringComparison.InvariantCultureIgnoreCase) == true) + toMove.Add(q); // now move these for (int i = 0; i < toMove.Count; i++) { - var q = toMove[i]; + var q = toMove[ i ]; var ext = new Extension( name: q.Type, semanticId: q.SemanticId, valueType: q.ValueType, value: q.Value); @@ -596,35 +596,35 @@ public static void MigrateV20QualifiersToExtensions(this IReferable rf) public static ISubmodelElement FindSubmodelElementByIdShort(this IReferable referable, string idShort) { - if(string.IsNullOrEmpty(idShort)) + if (string.IsNullOrEmpty(idShort)) { throw new ArgumentNullException(nameof(idShort)); } - if(referable == null) + if (referable == null) { throw new ArgumentNullException(nameof(referable)); } - if(referable is Submodel submodel) + if (referable is Submodel submodel) { return submodel.FindFirstIdShortAs(idShort); } - else if(referable is ISubmodelElementCollection smColl) + else if (referable is ISubmodelElementCollection smColl) { return smColl.FindFirstIdShortAs(idShort); } - else if(referable is ISubmodelElementList smList) + else if (referable is ISubmodelElementList smList) { return smList.FindFirstIdShortAs(idShort); } - else if(referable is IEntity entity) + else if (referable is IEntity entity) { return entity.FindFirstIdShortAs(idShort); } - else if(referable is IAnnotatedRelationshipElement annotatedRelationshipElement) + else if (referable is IAnnotatedRelationshipElement annotatedRelationshipElement) { - return annotatedRelationshipElement.FindFirstIdShortAs(idShort) ; + return annotatedRelationshipElement.FindFirstIdShortAs(idShort); } else { @@ -632,4 +632,4 @@ public static ISubmodelElement FindSubmodelElementByIdShort(this IReferable refe } } } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/Extensions/ExtendISubmodelElement.cs b/src/AasxCsharpLibrary/Extensions/ExtendISubmodelElement.cs index 3dbfd73b1..38e3a11da 100644 --- a/src/AasxCsharpLibrary/Extensions/ExtendISubmodelElement.cs +++ b/src/AasxCsharpLibrary/Extensions/ExtendISubmodelElement.cs @@ -11,8 +11,10 @@ namespace Extensions public static class ExtendISubmodelElement { // constants - public static Type[] PROP_MLP = new Type[] { - typeof(MultiLanguageProperty), typeof(Property) }; + public static Type[] PROP_MLP = new Type[] + { + typeof(MultiLanguageProperty), typeof(Property) + }; #region AasxPackageExplorer @@ -67,35 +69,35 @@ public static void ValueFromText(this ISubmodelElement submodelElement, string t switch (submodelElement) { case Property property: - { - property.ValueFromText(text); - break; - } + { + property.ValueFromText(text); + break; + } case MultiLanguageProperty multiLanguageProperty: - { - multiLanguageProperty.ValueFromText(text, defaultLang); - break; - } + { + multiLanguageProperty.ValueFromText(text, defaultLang); + break; + } default: - { - throw new Exception("Unhandled submodel element type"); - } + { + throw new Exception("Unhandled submodel element type"); + } } } #endregion + public static IEnumerable FindAllParents(this ISubmodelElement submodelElement, - Predicate p, - bool includeThis = false, bool includeSubmodel = false, - bool passOverMiss = false) + Predicate p, + bool includeThis = false, bool includeSubmodel = false, + bool passOverMiss = false) { // call for this? if (includeThis) { if (p == null || p.Invoke(submodelElement)) yield return submodelElement; - else - if (!passOverMiss) + else if (!passOverMiss) yield break; } @@ -105,7 +107,7 @@ public static IEnumerable FindAllParents(this ISubmodelElement submo if (submodelElement.Parent is ISubmodelElement psme) { foreach (var q in psme.FindAllParents(p, includeThis: true, - passOverMiss: passOverMiss)) + passOverMiss: passOverMiss)) yield return q; } else if (includeSubmodel && submodelElement.Parent is Submodel psm) @@ -117,8 +119,8 @@ public static IEnumerable FindAllParents(this ISubmodelElement submo } public static IEnumerable FindAllParentsWithSemanticId( - this ISubmodelElement submodelElement, Reference semId, - bool includeThis = false, bool includeSubmodel = false, bool passOverMiss = false) + this ISubmodelElement submodelElement, Reference semId, + bool includeThis = false, bool includeSubmodel = false, bool passOverMiss = false) { return (FindAllParents(submodelElement, (rf) => (true == (rf as IHasSemantics)?.SemanticId?.Matches(semId, @@ -168,7 +170,6 @@ public static IQualifier FindQualifierOfType(this ISubmodelElement submodelEleme } return null; - } public static Reference GetModelReference(this ISubmodelElement sme, bool includeParents = true) @@ -195,7 +196,6 @@ public static Reference GetModelReference(this ISubmodelElement sme, bool includ keyList.Insert(0, currentParentKey); currentParent = referable.Parent; } - } var outputReference = new Reference(ReferenceTypes.ModelReference, keyList); @@ -207,7 +207,7 @@ public static IEnumerable FindDeep(this ISubmodelElement submodelElement) { if (submodelElement is T) { - yield return (T)submodelElement; + yield return (T) submodelElement; } foreach (var x in submodelElement.Descend().OfType()) @@ -290,7 +290,6 @@ public static ISubmodelElement ConvertFromV10(this ISubmodelElement submodelElem var newOutputVariables = new List(); if (!sourceOperation.valueIn.IsNullOrEmpty()) { - foreach (var inputVariable in sourceOperation.valueIn) { if (inputVariable.value.submodelElement != null) @@ -302,6 +301,7 @@ public static ISubmodelElement ConvertFromV10(this ISubmodelElement submodelElem } } } + if (!sourceOperation.valueOut.IsNullOrEmpty()) { foreach (var outputVariable in sourceOperation.valueOut) @@ -351,13 +351,14 @@ private static void BasicConversionFromV10(this ISubmodelElement submodelElement var keyType = Stringification.KeyTypesFromString(refKey.type); if (keyType != null) { - keyList.Add(new Key((KeyTypes)keyType, refKey.value)); + keyList.Add(new Key((KeyTypes) keyType, refKey.value)); } else { Console.WriteLine($"KeyType value {refKey.type} not found."); } } + submodelElement.SemanticId = new Reference(ReferenceTypes.ExternalReference, keyList); } @@ -389,9 +390,9 @@ private static void BasicConversionFromV10(this ISubmodelElement submodelElement if (!dataSpecification.IsEmpty) { submodelElement.EmbeddedDataSpecifications.Add( - new EmbeddedDataSpecification( - ExtensionsUtil.ConvertReferenceFromV10(dataSpecification, ReferenceTypes.ExternalReference), - null)); + new EmbeddedDataSpecification( + ExtensionsUtil.ConvertReferenceFromV10(dataSpecification, ReferenceTypes.ExternalReference), + null)); } } } @@ -469,7 +470,6 @@ public static ISubmodelElement ConvertFromV20(this ISubmodelElement submodelElem var newInOutVariables = new List(); if (!sourceOperation.inputVariable.IsNullOrEmpty()) { - foreach (var inputVariable in sourceOperation.inputVariable) { if (inputVariable.value.submodelElement != null) @@ -481,6 +481,7 @@ public static ISubmodelElement ConvertFromV20(this ISubmodelElement submodelElem } } } + if (!sourceOperation.outputVariable.IsNullOrEmpty()) { foreach (var outputVariable in sourceOperation.outputVariable) @@ -518,7 +519,7 @@ public static ISubmodelElement ConvertFromV20(this ISubmodelElement submodelElem if (outputSubmodelElement != null) { - outputSubmodelElement.BasicConversionFromV20(sourceSubmodelElement); + outputSubmodelElement.BasicConversionFromV20(sourceSubmodelElement); } } @@ -552,7 +553,7 @@ private static void BasicConversionFromV20(this ISubmodelElement submodelElement if (keyType == KeyTypes.ConceptDescription) keyType = KeyTypes.GlobalReference; - keyList.Add(new Key((KeyTypes)keyType, refKey.value)); + keyList.Add(new Key((KeyTypes) keyType, refKey.value)); } else { @@ -560,6 +561,7 @@ private static void BasicConversionFromV20(this ISubmodelElement submodelElement } } } + submodelElement.SemanticId = new Reference(ReferenceTypes.ExternalReference, keyList); } @@ -598,7 +600,7 @@ private static void BasicConversionFromV20(this ISubmodelElement submodelElement #region List public static IReferable FindReferableByReference( - this List submodelElements, Reference rf, int keyIndex) + this List submodelElements, Reference rf, int keyIndex) { return FindReferableByReference(submodelElements, rf?.Keys, keyIndex); } @@ -613,7 +615,7 @@ public static IReferable FindReferableByReference( // over all wrappers foreach (var smw in submodelElements) - if (smw != null && smw.IdShort.Equals(keys[keyIndex].Value, StringComparison.OrdinalIgnoreCase)) + if (smw != null && smw.IdShort.Equals(keys[ keyIndex ].Value, StringComparison.OrdinalIgnoreCase)) { // match on this level. Did we find a leaf element? if ((keyIndex + 1) >= keys.Count) @@ -626,6 +628,7 @@ public static IReferable FindReferableByReference( if (found != null) return found; } + // dive into SML? if (smw is SubmodelElementList submodelElementList) { @@ -669,8 +672,8 @@ public static IEnumerable FindDeep(this List submodelEle // call lambda for this element if (current is T) - if (match == null || match.Invoke((T)current)) - yield return (T)current; + if (match == null || match.Invoke((T) current)) + yield return (T) current; // dive into? // TODO (MIHO, 2020-07-31): would be nice to use IEnumerateChildren for this .. @@ -714,18 +717,18 @@ public static IEnumerable FindDeep(this List submodelEle } public static void CopyManySMEbyCopy(this List submodelElements, ConceptDescription destCD, - List sourceSmc, ConceptDescription sourceCD, - bool createDefault = false, Action setDefault = null, - MatchMode matchMode = MatchMode.Relaxed) where T : ISubmodelElement + List sourceSmc, ConceptDescription sourceCD, + bool createDefault = false, Action setDefault = null, + MatchMode matchMode = MatchMode.Relaxed) where T : ISubmodelElement { submodelElements.CopyManySMEbyCopy(destCD.GetSingleKey(), sourceSmc, sourceCD.GetSingleKey(), createDefault ? destCD : null, setDefault, matchMode); } public static void CopyManySMEbyCopy(this List submodelElements, Key destSemanticId, - List sourceSmc, Key sourceSemanticId, - ConceptDescription createDefault = null, Action setDefault = null, - MatchMode matchMode = MatchMode.Relaxed) where T : ISubmodelElement + List sourceSmc, Key sourceSemanticId, + ConceptDescription createDefault = null, Action setDefault = null, + MatchMode matchMode = MatchMode.Relaxed) where T : ISubmodelElement { // bool find possible sources bool foundSrc = false; @@ -734,7 +737,7 @@ public static void CopyManySMEbyCopy(this List submodelElem foreach (var src in sourceSmc.FindAllSemanticIdAs(sourceSemanticId, matchMode)) { // type of found src? - AasSubmodelElements aeSrc = (AasSubmodelElements)Enum.Parse(typeof(AasSubmodelElements), src.GetType().Name); + AasSubmodelElements aeSrc = (AasSubmodelElements) Enum.Parse(typeof(AasSubmodelElements), src.GetType().Name); // ok? if (src == null || aeSrc == AasSubmodelElements.SubmodelElement) @@ -748,7 +751,7 @@ public static void CopyManySMEbyCopy(this List submodelElem // make same things sure dst.IdShort = src.IdShort; dst.Category = src.Category; - dst.SemanticId = new Reference(ReferenceTypes.ModelReference, new List() { destSemanticId }); + dst.SemanticId = new Reference(ReferenceTypes.ModelReference, new List() {destSemanticId}); // instantanously add it? submodelElements.Add(dst); @@ -767,30 +770,30 @@ public static void CopyManySMEbyCopy(this List submodelElem } public static T CopyOneSMEbyCopy(this List submodelElements, ConceptDescription destCD, - List sourceSmc, Key[] sourceKeys, - bool createDefault = false, Action setDefault = null, - MatchMode matchMode = MatchMode.Relaxed, - string idShort = null, bool addSme = false) where T : ISubmodelElement + List sourceSmc, Key[] sourceKeys, + bool createDefault = false, Action setDefault = null, + MatchMode matchMode = MatchMode.Relaxed, + string idShort = null, bool addSme = false) where T : ISubmodelElement { return submodelElements.CopyOneSMEbyCopy(destCD?.GetSingleKey(), sourceSmc, sourceKeys, createDefault ? destCD : null, setDefault, matchMode, idShort, addSme); } public static T CopyOneSMEbyCopy(this List submodelELements, ConceptDescription destCD, - List sourceSmc, ConceptDescription sourceCD, - bool createDefault = false, Action setDefault = null, - MatchMode matchMode = MatchMode.Relaxed, - string idShort = null, bool addSme = false) where T : ISubmodelElement + List sourceSmc, ConceptDescription sourceCD, + bool createDefault = false, Action setDefault = null, + MatchMode matchMode = MatchMode.Relaxed, + string idShort = null, bool addSme = false) where T : ISubmodelElement { - return submodelELements.CopyOneSMEbyCopy(destCD?.GetSingleKey(), sourceSmc, new[] { sourceCD?.GetSingleKey() }, + return submodelELements.CopyOneSMEbyCopy(destCD?.GetSingleKey(), sourceSmc, new[] {sourceCD?.GetSingleKey()}, createDefault ? destCD : null, setDefault, matchMode, idShort, addSme); } public static T CopyOneSMEbyCopy(this List submodelElements, Key destSemanticId, - List sourceSmc, Key[] sourceSemanticId, - ConceptDescription createDefault = null, Action setDefault = null, - MatchMode matchMode = MatchMode.Relaxed, - string idShort = null, bool addSme = false) where T : ISubmodelElement + List sourceSmc, Key[] sourceSemanticId, + ConceptDescription createDefault = null, Action setDefault = null, + MatchMode matchMode = MatchMode.Relaxed, + string idShort = null, bool addSme = false) where T : ISubmodelElement { // get source var src = sourceSmc.FindFirstAnySemanticIdAs(sourceSemanticId, matchMode); @@ -800,11 +803,11 @@ public static T CopyOneSMEbyCopy(this List submodelElements { var anySrc = sourceSmc?.FindFirstAnySemanticId(sourceSemanticId, matchMode: matchMode); src = submodelElements.AdaptiveConvertTo(anySrc, createDefault, - idShort: idShort, addSme: false); + idShort: idShort, addSme: false); } // proceed - AasSubmodelElements aeSrc = (AasSubmodelElements)Enum.Parse(typeof(AasSubmodelElements), src?.GetType().Name); + AasSubmodelElements aeSrc = (AasSubmodelElements) Enum.Parse(typeof(AasSubmodelElements), src?.GetType().Name); if (src == null || aeSrc == AasSubmodelElements.SubmodelElement) { // create a default? @@ -829,35 +832,35 @@ public static T CopyOneSMEbyCopy(this List submodelElements // make same things sure dst.IdShort = src.IdShort; dst.Category = src.Category; - dst.SemanticId = new Reference(ReferenceTypes.ModelReference, new List() { destSemanticId }); + dst.SemanticId = new Reference(ReferenceTypes.ModelReference, new List() {destSemanticId}); // instantanously add it? if (addSme) submodelElements.Add(dst); // give back - return (T)dst; + return (T) dst; } public static T AdaptiveConvertTo(this List submodelElements, - ISubmodelElement anySrc, - ConceptDescription createDefault = null, - string idShort = null, bool addSme = false) where T : ISubmodelElement + ISubmodelElement anySrc, + ConceptDescription createDefault = null, + string idShort = null, bool addSme = false) where T : ISubmodelElement { if (typeof(T) == typeof(MultiLanguageProperty) - && anySrc is Property srcProp) + && anySrc is Property srcProp) { var res = submodelElements.CreateSMEForCD(createDefault, idShort: idShort, addSme: addSme); if (res is MultiLanguageProperty mlp) { - mlp.Value = new List() { new LangStringTextType("EN?", srcProp.Value) }; + mlp.Value = new List() {new LangStringTextType("EN?", srcProp.Value)}; mlp.ValueId = srcProp.ValueId; return res; } } if (typeof(T) == typeof(Property) - && anySrc is MultiLanguageProperty srcMlp) + && anySrc is MultiLanguageProperty srcMlp) { var res = submodelElements.CreateSMEForCD(createDefault, idShort: idShort, addSme: addSme); if (res is Property prp) @@ -903,22 +906,23 @@ public static T FindFirstIdShortAs(this List submodelElemen public static ISubmodelElement FindFirstAnySemanticId(this List submodelElements, - Key[] semId, Type[] allowedTypes = null, MatchMode matchMode = MatchMode.Strict) + Key[] semId, Type[] allowedTypes = null, MatchMode matchMode = MatchMode.Strict) { if (semId == null) return null; foreach (var si in semId) { var found = submodelElements.FindAllSemanticId(si, allowedTypes, matchMode)? - .FirstOrDefault(); + .FirstOrDefault(); if (found != null) return found; } + return null; } public static T FindFirstAnySemanticIdAs(this List submodelElements, Key[] semId, MatchMode matchMode = MatchMode.Strict) - where T : ISubmodelElement + where T : ISubmodelElement { if (semId == null) return default(T); @@ -928,11 +932,12 @@ public static T FindFirstAnySemanticIdAs(this List submodel if (found != null) return found; } + return default(T); } public static T CreateNew(string idShort = null, string category = null, Reference semanticId = null) - where T : ISubmodelElement, new() + where T : ISubmodelElement, new() { var res = new T(); if (idShort != null) @@ -945,8 +950,8 @@ public static T CreateNew(string idShort = null, string category = null, Refe } public static T CreateSMEForCD(this List submodelELements, ConceptDescription conceptDescription, string category = null, string idShort = null, - string idxTemplate = null, int maxNum = 999, bool addSme = false, bool isTemplate = false) - where T : ISubmodelElement + string idxTemplate = null, int maxNum = 999, bool addSme = false, bool isTemplate = false) + where T : ISubmodelElement { // access if (conceptDescription == null) @@ -994,28 +999,28 @@ public static T CreateSMEForCD(this List submodelELements, submodelELements.Add(sme); // give back - return (T)sme; + return (T) sme; } public static IEnumerable FindAllSemanticIdAs(this List submodelELements, Key semId, MatchMode matchMode = MatchMode.Strict) - where T : ISubmodelElement + where T : ISubmodelElement { foreach (var submodelElement in submodelELements) if (submodelElement != null && submodelElement is T - && submodelElement.SemanticId != null) + && submodelElement.SemanticId != null) if (submodelElement.SemanticId.MatchesExactlyOneKey(semId, matchMode)) - yield return (T)submodelElement; + yield return (T) submodelElement; } public static IEnumerable FindAllSemanticIdAs(this List submodelELements, Reference semId, MatchMode matchMode = MatchMode.Strict) - where T : ISubmodelElement + where T : ISubmodelElement { foreach (var submodelElement in submodelELements) if (submodelElement != null && submodelElement is T - && submodelElement.SemanticId != null) + && submodelElement.SemanticId != null) if (submodelElement.SemanticId.Matches(semId, matchMode)) - yield return (T)submodelElement; + yield return (T) submodelElement; } public static T FindFirstSemanticIdAs(this List submodelElements, @@ -1033,7 +1038,7 @@ public static T FindFirstSemanticIdAs(this List submodelEle } public static void RecurseOnReferables(this List submodelElements, object state, List parents, - Func, IReferable, bool> lambda) + Func, IReferable, bool> lambda) { if (lambda == null) return; @@ -1092,6 +1097,7 @@ public static void RecurseOnReferables(this List submodelEleme { annotationElements.Add(annotation); } + annotationElements.RecurseOnReferables(state, parents, lambda); } @@ -1101,7 +1107,8 @@ public static void RecurseOnReferables(this List submodelEleme } } - public static void RecurseOnSubmodelElements(this List submodelElements, object state, List parents, Action, ISubmodelElement> lambda) + public static void RecurseOnSubmodelElements(this List submodelElements, object state, List parents, + Action, ISubmodelElement> lambda) { // trivial if (lambda == null) @@ -1157,6 +1164,7 @@ public static void RecurseOnSubmodelElements(this List submode { annotationElements.Add(annotation); } + annotationElements.RecurseOnSubmodelElements(state, parents, lambda); } @@ -1173,7 +1181,7 @@ public static IEnumerable FindAllSemanticIdAs(this List { if (submodelElement.SemanticId.Matches(semanticId)) { - yield return (T)submodelElement; + yield return (T) submodelElement; } } } @@ -1194,6 +1202,7 @@ public static T FindFirstAnySemanticIdAs(this List submodel if (found != null) return found; } + return default; } @@ -1213,7 +1222,7 @@ public static IEnumerable FindAllSemanticId( if (sme.SemanticId == null || sme.SemanticId.Keys.Count < 1) { if (invertedAllowed) - yield return (T)sme; + yield return (T) sme; continue; } @@ -1229,7 +1238,7 @@ public static IEnumerable FindAllSemanticId( found = !found; if (found) - yield return (T)sme; + yield return (T) sme; } } @@ -1254,7 +1263,7 @@ public static IEnumerable FindAllSemanticId( if (sme.SemanticId == null || sme.SemanticId.Keys.Count < 1) { if (invertedAllowed) - yield return (T)sme; + yield return (T) sme; continue; } @@ -1270,7 +1279,7 @@ public static IEnumerable FindAllSemanticId( found = !found; if (found) - yield return (T)sme; + yield return (T) sme; } } @@ -1305,7 +1314,8 @@ public static IEnumerable FindAllSemanticId( } } - public static ISubmodelElement FindFirstSemanticId(this List submodelElements, Key semId, Type[] allowedTypes = null, MatchMode matchMode = MatchMode.Strict) + public static ISubmodelElement FindFirstSemanticId(this List submodelElements, Key semId, Type[] allowedTypes = null, + MatchMode matchMode = MatchMode.Strict) { return submodelElements.FindAllSemanticId(semId, allowedTypes, matchMode)?.FirstOrDefault(); } @@ -1313,7 +1323,7 @@ public static ISubmodelElement FindFirstSemanticId(this List s public static IEnumerable FindAllSemanticIdAs( this List smes, ConceptDescription cd, MatchMode matchMode = MatchMode.Strict) - where T : ISubmodelElement + where T : ISubmodelElement { foreach (var x in FindAllSemanticIdAs(smes, cd.GetReference(), matchMode)) yield return x; @@ -1322,7 +1332,7 @@ public static IEnumerable FindAllSemanticIdAs( public static T FindFirstSemanticIdAs( this List smes, ConceptDescription cd, MatchMode matchMode = MatchMode.Strict) - where T : ISubmodelElement + where T : ISubmodelElement { return smes.FindAllSemanticIdAs(cd, matchMode).FirstOrDefault(); } @@ -1400,23 +1410,23 @@ public static ISubmodelElement UpdateFrom(this ISubmodelElement elem, ISubmodelE private static readonly Dictionary AasSubmodelElementsToAbbrev = ( new Dictionary() { - { AasSubmodelElements.AnnotatedRelationshipElement, "RelA" }, - { AasSubmodelElements.BasicEventElement, "BEvt" }, - { AasSubmodelElements.Blob, "Blob" }, - { AasSubmodelElements.Capability, "Cap" }, - { AasSubmodelElements.DataElement, "DE" }, - { AasSubmodelElements.Entity, "Ent" }, - { AasSubmodelElements.EventElement, "Evt" }, - { AasSubmodelElements.File, "File" }, - { AasSubmodelElements.MultiLanguageProperty, "MLP" }, - { AasSubmodelElements.Operation, "Opr" }, - { AasSubmodelElements.Property, "Prop" }, - { AasSubmodelElements.Range, "Range" }, - { AasSubmodelElements.ReferenceElement, "Ref" }, - { AasSubmodelElements.RelationshipElement, "Rel" }, - { AasSubmodelElements.SubmodelElement, "SME" }, - { AasSubmodelElements.SubmodelElementList, "SML" }, - { AasSubmodelElements.SubmodelElementCollection, "SMC" } + {AasSubmodelElements.AnnotatedRelationshipElement, "RelA"}, + {AasSubmodelElements.BasicEventElement, "BEvt"}, + {AasSubmodelElements.Blob, "Blob"}, + {AasSubmodelElements.Capability, "Cap"}, + {AasSubmodelElements.DataElement, "DE"}, + {AasSubmodelElements.Entity, "Ent"}, + {AasSubmodelElements.EventElement, "Evt"}, + {AasSubmodelElements.File, "File"}, + {AasSubmodelElements.MultiLanguageProperty, "MLP"}, + {AasSubmodelElements.Operation, "Opr"}, + {AasSubmodelElements.Property, "Prop"}, + {AasSubmodelElements.Range, "Range"}, + {AasSubmodelElements.ReferenceElement, "Ref"}, + {AasSubmodelElements.RelationshipElement, "Rel"}, + {AasSubmodelElements.SubmodelElement, "SME"}, + {AasSubmodelElements.SubmodelElementList, "SML"}, + {AasSubmodelElements.SubmodelElementCollection, "SMC"} }); /// @@ -1447,23 +1457,23 @@ public static ISubmodelElement UpdateFrom(this ISubmodelElement elem, ISubmodelE private static readonly Dictionary _aasSubmodelElementsFromAbbrev = ( new Dictionary() { - { "RelA", AasSubmodelElements.AnnotatedRelationshipElement }, - { "BEvt", AasSubmodelElements.BasicEventElement }, - { "Blob", AasSubmodelElements.Blob }, - { "Cap", AasSubmodelElements.Capability }, - { "DE", AasSubmodelElements.DataElement }, - { "Ent", AasSubmodelElements.Entity }, - { "Evt", AasSubmodelElements.EventElement }, - { "File", AasSubmodelElements.File }, - { "MLP", AasSubmodelElements.MultiLanguageProperty }, - { "Opr", AasSubmodelElements.Operation }, - { "Prop", AasSubmodelElements.Property }, - { "Range", AasSubmodelElements.Range }, - { "Ref", AasSubmodelElements.ReferenceElement }, - { "Rel", AasSubmodelElements.RelationshipElement }, - { "SME", AasSubmodelElements.SubmodelElement }, - { "SML", AasSubmodelElements.SubmodelElementList }, - { "SMC", AasSubmodelElements.SubmodelElementCollection } + {"RelA", AasSubmodelElements.AnnotatedRelationshipElement}, + {"BEvt", AasSubmodelElements.BasicEventElement}, + {"Blob", AasSubmodelElements.Blob}, + {"Cap", AasSubmodelElements.Capability}, + {"DE", AasSubmodelElements.DataElement}, + {"Ent", AasSubmodelElements.Entity}, + {"Evt", AasSubmodelElements.EventElement}, + {"File", AasSubmodelElements.File}, + {"MLP", AasSubmodelElements.MultiLanguageProperty}, + {"Opr", AasSubmodelElements.Operation}, + {"Prop", AasSubmodelElements.Property}, + {"Range", AasSubmodelElements.Range}, + {"Ref", AasSubmodelElements.ReferenceElement}, + {"Rel", AasSubmodelElements.RelationshipElement}, + {"SME", AasSubmodelElements.SubmodelElement}, + {"SML", AasSubmodelElements.SubmodelElementList}, + {"SMC", AasSubmodelElements.SubmodelElementCollection} }); /// @@ -1502,6 +1512,5 @@ public static ISubmodelElement UpdateFrom(this ISubmodelElement elem, ISubmodelE return AasSubmodelElementsFromAbbrev(text); } - } -} +} \ No newline at end of file diff --git a/src/AasxCsharpLibrary/IAasxOnlineConnection.cs b/src/AasxCsharpLibrary/IAasxOnlineConnection.cs index 8f2ca66cf..5253465bd 100644 --- a/src/AasxCsharpLibrary/IAasxOnlineConnection.cs +++ b/src/AasxCsharpLibrary/IAasxOnlineConnection.cs @@ -12,7 +12,7 @@ This source code may use other Open Source software components (see LICENSE.txt) namespace AasxIntegrationBase { /// - /// This interface describes a connection for a server resource of AASX contents, such as OPC UA or REST + /// This interface describes a connection for a server resource of AASX contents, such as REST /// public interface IAasxOnlineConnection { diff --git a/src/AasxServer.sln b/src/AasxServer.sln index c2f479764..c0cdb4a02 100644 --- a/src/AasxServer.sln +++ b/src/AasxServer.sln @@ -7,12 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxServerStandardBib", "Aa EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B8C116C4-932B-4071-9DCC-D4F64E3C4E6F}" ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore ..\CHANGELOG.md = ..\CHANGELOG.md ..\README.md = ..\README.md ..\CONTRIBUTING.md = ..\CONTRIBUTING.md ..\LICENSE.TXT = ..\LICENSE.TXT ..\CONTRIBUTORS.md = ..\CONTRIBUTORS.md + ..\.gitignore = ..\.gitignore EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "jsoncanonicalizer", "jsoncanonicalizer\jsoncanonicalizer.csproj", "{A420D3A9-3725-4F4D-9185-2957F2F9F0A9}" @@ -37,6 +37,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleClient", "ExampleCli EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AasxServerAspNetCore", "AasxServerAspNetCore\AasxServerAspNetCore.csproj", "{D467D497-18D8-4E26-8671-8AC73BE9AC4F}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F847719C-7CF2-40D5-BF7B-6F51E551E13F}" + ProjectSection(SolutionItems) = preProject + ..\.github\ISSUE_TEMPLATE\BugReport.yml = ..\.github\ISSUE_TEMPLATE\BugReport.yml + ..\.github\workflows\build-and-package-release.yml = ..\.github\workflows\build-and-package-release.yml + ..\.github\workflows\build-and-publish-docker-images.yml = ..\.github\workflows\build-and-publish-docker-images.yml + ..\.github\workflows\build-and-publish-docker-images-release.yml = ..\.github\workflows\build-and-publish-docker-images-release.yml + ..\.github\workflows\build-docker-images.yml = ..\.github\workflows\build-docker-images.yml + ..\.github\workflows\check-release.yml = ..\.github\workflows\check-release.yml + ..\.github\workflows\check-style.yml = ..\.github\workflows\check-style.yml + ..\.github\ISSUE_TEMPLATE\FeatureRequest.yml = ..\.github\ISSUE_TEMPLATE\FeatureRequest.yml + ..\.github\pull_request_template.md = ..\.github\pull_request_template.md + ..\.github\ISSUE_TEMPLATE\Questions_and_help.md = ..\.github\ISSUE_TEMPLATE\Questions_and_help.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -273,4 +287,7 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A6054B71-0BA2-4582-9B76-805D46670242} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F847719C-7CF2-40D5-BF7B-6F51E551E13F} = {B8C116C4-932B-4071-9DCC-D4F64E3C4E6F} + EndGlobalSection EndGlobal diff --git a/src/AasxServerAspNetCore/AasxServerAspNetCore.csproj b/src/AasxServerAspNetCore/AasxServerAspNetCore.csproj index 51ef6d88c..c9cd7f7a7 100644 --- a/src/AasxServerAspNetCore/AasxServerAspNetCore.csproj +++ b/src/AasxServerAspNetCore/AasxServerAspNetCore.csproj @@ -1,32 +1,32 @@ - - net6.0 - enable - enable - - - false - + + net6.0 + enable + enable + + + false + - - - - - + + + + + - - - - + + + + - - - Always - - - Always - - + + + Always + + + Always + + diff --git a/src/AasxServerAspNetCore/Startup.cs b/src/AasxServerAspNetCore/Startup.cs index 05d910cad..54e7e4564 100644 --- a/src/AasxServerAspNetCore/Startup.cs +++ b/src/AasxServerAspNetCore/Startup.cs @@ -67,7 +67,6 @@ public void ConfigureServices(IServiceCollection services) services.AddControllers(); services.AddLazyResolution(); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>)); @@ -156,10 +155,7 @@ public void ConfigureServices(IServiceCollection services) c.OperationFilter(); }); - - - services.AddAuthentication("AasSecurityAuth") - .AddScheme("AasSecurityAuth", null); + services.AddAuthorization(c => { c.AddPolicy("SecurityPolicy", policy => diff --git a/src/AasxServerBlazor/AasxServerBlazor.csproj b/src/AasxServerBlazor/AasxServerBlazor.csproj index 109a6a7a9..3e0946ff9 100644 --- a/src/AasxServerBlazor/AasxServerBlazor.csproj +++ b/src/AasxServerBlazor/AasxServerBlazor.csproj @@ -1,86 +1,90 @@  - - net6.0 - en-US;de-DE - + + net6.0 + en-US;de-DE + - - DEBUG;TRACE;UseAasxCompatibilityModels - portable - true - + + DEBUG;TRACE;UseAasxCompatibilityModels + portable + true + - - false - + + false + - - - + + + - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + - - - - - - - - - - + + + + + + + + + + - + + + + + - - - PreserveNewest - + + + PreserveNewest + - - PreserveNewest - - + + PreserveNewest + + - - - Always - - + + + Always + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - - PreserveNewest - - + + + PreserveNewest + + diff --git a/src/AasxServerBlazor/BlazorServerStarter.cs b/src/AasxServerBlazor/BlazorServerStarter.cs index 67a10183b..68c0a15d5 100644 --- a/src/AasxServerBlazor/BlazorServerStarter.cs +++ b/src/AasxServerBlazor/BlazorServerStarter.cs @@ -49,7 +49,7 @@ private static IHostBuilder CreateHostBuilder(string[] args, IConfiguration conf { Program.blazorPort = url[2]; } - + return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { diff --git a/src/AasxServerBlazor/Configuration/DependencyRegistry.cs b/src/AasxServerBlazor/Configuration/DependencyRegistry.cs index 8ee4a4aaa..a120de99e 100644 --- a/src/AasxServerBlazor/Configuration/DependencyRegistry.cs +++ b/src/AasxServerBlazor/Configuration/DependencyRegistry.cs @@ -26,7 +26,6 @@ public static void Register(IServiceCollection services) services.AddSingleton(); services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>)); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddTransient(); diff --git a/src/AasxServerBlazor/Configuration/ServerConfiguration.cs b/src/AasxServerBlazor/Configuration/ServerConfiguration.cs index e3d8c701d..c6c1ecaf2 100644 --- a/src/AasxServerBlazor/Configuration/ServerConfiguration.cs +++ b/src/AasxServerBlazor/Configuration/ServerConfiguration.cs @@ -65,9 +65,6 @@ public static void AddFrameworkServices(IServiceCollection services) AddMvc(services); AddSwaggerGen(services); - services.AddAuthentication(AuthenticationScheme) - .AddScheme(AuthenticationScheme, null); - AddAuthorization(services); } diff --git a/src/AasxServerBlazor/Pages/Pcf2.razor b/src/AasxServerBlazor/Pages/Pcf2.razor index 22fcab943..bc7029f92 100644 --- a/src/AasxServerBlazor/Pages/Pcf2.razor +++ b/src/AasxServerBlazor/Pages/Pcf2.razor @@ -353,28 +353,31 @@ var registry = AasRegistryService.GetRegistryList(); if (registry.Count != 0) { + string registryURL = registry[0]; + // check for buffered shell descriptors from getregistry() for basyx var aasDescriptors = AasRegistryService.GetAasDescriptorsForSubmodelView(); - if (aasDescriptors != null && aasDescriptors.Count != 0) { - string registryURL = NavMan.Uri; + registryURL = NavMan.Uri; registryURL = registryURL.Substring(0, registryURL.Length - "/pcf".Length); Console.WriteLine("registryURL " + registryURL); - link += "®istryURL=" + registryURL; } - else + + if (AasxCredentials.get(cs.credentials, registryURL, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) { - link += "®istryURL=" + registry[0]; + if (replace != "") + registryURL = replace; } + + link += "®istryURL=" + registryURL; } - // JUIJUI queryPara = ""; userPW = ""; urlEdcWrapper = ""; replace = ""; - if (AasxCredentials.get(cs.credentials, link, out queryPara, out userPW, out urlEdcWrapper, out replace)) + if (AasxCredentials.get(cs.credentials, link, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) { if (replace != "") link = replace; @@ -383,7 +386,6 @@ queryPara = Base64UrlEncoder.Encode(queryPara); link += "&query=" + queryPara; } - // Console.WriteLine("iframe:" + link); } if (node.aas != null) @@ -492,7 +494,7 @@ } var icon = id; - if (AasxCredentials.get(cs.credentials, smlink, out queryPara, out userPW, out urlEdcWrapper, out replace)) + if (AasxCredentials.get(cs.credentials, smlink, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) { if (replace != "") smlink = replace; @@ -689,7 +691,7 @@ string userPW = ""; string urlEdcWrapper = ""; string replace = ""; - if (AasxCredentials.get(credentials, path, out queryPara, out userPW, out urlEdcWrapper, out replace)) + if (AasxCredentials.get(credentials, path, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) { if (replace != "") path = replace; diff --git a/src/AasxServerBlazor/Properties/launchSettings.json b/src/AasxServerBlazor/Properties/launchSettings.json new file mode 100644 index 000000000..a98906cea --- /dev/null +++ b/src/AasxServerBlazor/Properties/launchSettings.json @@ -0,0 +1,32 @@ +{ + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "commandLineArgs": "--port 51710 --data-path C:\\Develop\\Aasx\\repo --edit --secret-string=123", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "AasxServerBlazor": { + "commandName": "Project", + "commandLineArgs": "--no-security --secret-string-api 1234 --aasx-in-memory 1000 --data-path \"C:\\Development\" --edit --external-blazor http://localhost:5001", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "AASREGISTRY": "https://registry.dpp40-2-v2.industrialdigitaltwin.org", + "IFRAMEPATH": "https://dpp40-2-v2.industrialdigitaltwin.org/dashboard/submodelViewV3.html" + }, + "applicationUrl": "http://localhost:5001", + "jsWebView2Debugging": true + } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:56189", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/src/AasxServerBlazor/Shared/MainLayout.razor b/src/AasxServerBlazor/Shared/MainLayout.razor index 0632b01b8..1473720dc 100644 --- a/src/AasxServerBlazor/Shared/MainLayout.razor +++ b/src/AasxServerBlazor/Shared/MainLayout.razor @@ -301,26 +301,35 @@ { if (env != null) { + var queryPara = ""; + var userPW = ""; + var urlEdcWrapper = ""; + string replace = ""; + var aas = env.AasEnv.AssetAdministrationShells[0]; if (aas.IdShort != "ZveiControlCabinetAas - EXTERNAL") continue; - link = "?aasUrl=" + getAasLink(aas); + link = getAasLink(aas); - // var registry = IO.Swagger.Registry.Controllers.RegistryAndDiscoveryInterfaceApiController.getRegistry; - // JUIJUI var registry = AasRegistryService.GetRegistryList(); if (registry != null && registry.Count != 0) { - link += "®istryURL=" + registry[0]; + string registryURL = registry[0]; + + if (AasxCredentials.get(cs.credentials, registryURL, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) + { + if (replace != "") + registryURL = replace; + } + link += "®istryURL=" + registryURL; } - // JUIJUI - var queryPara = ""; - var userPW = ""; - var urlEdcWrapper = ""; - string replace = ""; - if (AasxCredentials.get(cs.credentials, link, out queryPara, out userPW, out urlEdcWrapper, out replace)) + queryPara = ""; + userPW = ""; + urlEdcWrapper = ""; + replace = ""; + if (AasxCredentials.get(cs.credentials, link, out queryPara, out userPW, out urlEdcWrapper, out replace, true)) { if (replace != "") link = replace; @@ -329,6 +338,7 @@ // Console.WriteLine("iframe:" + link); } + link = "?aasUrl=" + link; } } diff --git a/src/AasxServerBlazor/Startup.cs b/src/AasxServerBlazor/Startup.cs index 6da9027d7..6b60d2efa 100644 --- a/src/AasxServerBlazor/Startup.cs +++ b/src/AasxServerBlazor/Startup.cs @@ -14,7 +14,7 @@ public Startup(IConfiguration configuration) } private IConfiguration Configuration { get; } - + /// /// Configures the services for the application's dependency injection container. /// This method is called by the runtime. Use it to add services required by the application. @@ -30,7 +30,7 @@ public void ConfigureServices(IServiceCollection services) ServerConfiguration.AddFrameworkServices(services); } - + /// /// Configures the HTTP request pipeline for the application. /// This method is called by the runtime. Use it to define how incoming requests are handled. diff --git a/src/AasxServerStandardBib/AasEntityBuilder.cs b/src/AasxServerStandardBib/AasEntityBuilder.cs deleted file mode 100644 index 1e17f725e..000000000 --- a/src/AasxServerStandardBib/AasEntityBuilder.cs +++ /dev/null @@ -1,823 +0,0 @@ -/* -Copyright (c) 2018-2019 Festo AG & Co. KG -Author: Michael Hoffmeister - -This source code is licensed under the Apache License 2.0 (see LICENSE.txt). - -This source code may use other Open Source software components (see LICENSE.txt). -*/ - - -using AdminShellNS; -using Extensions; -using Opc.Ua; -using System.Collections.Generic; - -namespace AasOpcUaServer -{ - public class AasEntityBuilder - { - //// Static singleton for AAS entity builders - // ugly, but simple: the singleton variables gives access to information - // - public static AasModeManager nodeMgr = null; - - public AdminShellPackageEnv[] packages = null; - - public AasxUaServerOptions theServerOptions = null; - - public IDictionary> nodeMgrExternalReferences = null; - - /// - /// Root of AASes - /// - public NodeState RootAAS = null; - - /// - /// Root for CDs - /// - public NodeState RootConceptDescriptions = null; - - /// - /// Root for DataSpecifications - /// - public NodeState RootDataSpecifications = null; - - /// - /// Provide a root node, if semantic ids shall create missing dictionary entry (targets), - /// which can not be found in the AAS environment. - /// - public NodeState RootMissingDictionaryEntries = null; - - public AasEntityBuilder(AasModeManager nodeMgr, AdminShellPackageEnv[] package, - IDictionary> externalReferences, AasxUaServerOptions options) - { - AasEntityBuilder.nodeMgr = nodeMgr; - this.packages = package; - this.nodeMgrExternalReferences = externalReferences; - this.aasTypes = new AasTypeEntities(); - this.theServerOptions = options; - this.aasTypes.BuildEntites(this); - } - - public class NodeRecord - { - public NodeState uanode = null; - public IReferable referable = null; - public string identification = null; - - public NodeRecord() { } - public NodeRecord(NodeState uanode, IReferable referable) - { - this.uanode = uanode; - this.referable = referable; - } - public NodeRecord(NodeState uanode, string identification) - { - this.uanode = uanode; - this.identification = identification; - } - } - - private Dictionary NodeRecordFromReferable - = new Dictionary(); - private Dictionary NodeRecordFromIdentificationHash - = new Dictionary(); - - /// - /// Use this function always to remeber new node records. - /// - /// - public void AddNodeRecord(NodeRecord nr) - { - if (nr.referable != null && !NodeRecordFromReferable.ContainsKey(nr.referable)) - NodeRecordFromReferable.Add(nr.referable, nr); - - if (nr.identification != null && nr.identification != "") - { - var hash = "" + nr.identification.Trim().ToUpper(); - if (!NodeRecordFromIdentificationHash.ContainsKey(hash)) - NodeRecordFromIdentificationHash.Add(hash, nr); - } - } - - /// - /// Use this always to lookup node records from Referable - /// - /// - /// - public NodeRecord LookupNodeRecordFromReferable(IReferable referable) - { - if (NodeRecordFromReferable == null || !NodeRecordFromReferable.ContainsKey(referable)) - return null; - return NodeRecordFromReferable[referable]; - } - - /// - /// Use this always to lookup node records from Indentifiable - /// - /// - /// - public NodeRecord LookupNodeRecordFromIdentification(string identification) - { - var hash = "" + identification.Trim().ToUpper(); - if (NodeRecordFromReferable == null || !NodeRecordFromIdentificationHash.ContainsKey(hash)) - return null; - return NodeRecordFromIdentificationHash[hash]; - } - - /// - /// Base class for actions, which shall be done on the 2nd pass of the information model building - /// - public class NodeLateAction - { - public NodeState uanode = null; - } - - /// - /// Make a late reference to another node identified by a AAS reference information - /// - public class NodeLateActionLinkToReference : NodeLateAction - { - public enum ActionType { None, SetAasReference, SetDictionaryEntry } - - public Reference targetReference = null; - public ActionType actionType = ActionType.None; - - public NodeLateActionLinkToReference(NodeState uanode, Reference targetReference, - ActionType actionType) - { - this.uanode = uanode; - this.targetReference = targetReference; - this.actionType = actionType; - } - } - - private List noteLateActions = new List(); - - /// - /// Add a late action, which will be processed as 2nd phase of info model preparation - /// - /// - public void AddNodeLateAction(NodeLateAction la) - { - this.noteLateActions.Add(la); - } - - private IReferable FindAllReferableByReference(AdminShellPackageEnv[] packages, - Reference rf) - { - // access - if (packages == null || rf == null) - return null; - - // find - foreach (var pck in packages) - { - var x = pck?.AasEnv?.FindReferableByReference(rf); - if (x != null) - return x; - } - - // oh, no - return null; - } - - /// - /// Top level creation functions. Uses the definitions of RootAAS, RootConceptDescriptions, - /// RootDataSpecifications to synthesize information model - /// - public void CreateAddInstanceObjects(AasCore.Aas3_0.Environment env) - { - if (RootAAS == null) - return; - - // CDs (build 1st to be "remembered" as targets for "HasDictionaryEntry") - if (env.ConceptDescriptions != null && this.RootConceptDescriptions != null) - foreach (var cd in env.ConceptDescriptions) - { - this.AasTypes.ConceptDescription.CreateAddElements(this.RootConceptDescriptions, - AasUaBaseEntity.CreateMode.Instance, cd); - } - - // AAS - if (env.AssetAdministrationShells != null) - foreach (var aas in env.AssetAdministrationShells) - this.AasTypes.AAS.CreateAddInstanceObject(RootAAS, env, aas); - - // go through late actions - foreach (var la in this.noteLateActions) - { - // make a Reference ?? - var lax = la as NodeLateActionLinkToReference; - - // more simple case: AasReference between known entities - if (lax != null && lax.actionType == NodeLateActionLinkToReference.ActionType.SetAasReference - && lax.uanode != null - && this.packages != null) - { - // 1st, take reference and turn it into Referable - var targetReferable = FindAllReferableByReference(this.packages, lax.targetReference); - if (targetReferable == null) - continue; - - // 2nd, try to lookup the Referable and turn it into a uanode - var targetNodeRec = this.LookupNodeRecordFromReferable(targetReferable); - if (targetNodeRec == null || targetNodeRec.uanode == null) - continue; - - // now, we have everything to formulate a reference - if (!lax.uanode.ReferenceExists(this.AasTypes.HasAasReference.GetTypeNodeId(), false, - targetNodeRec.uanode.NodeId)) - { - lax.uanode.AddReference(this.AasTypes.HasAasReference.GetTypeNodeId(), false, - targetNodeRec.uanode.NodeId); - } - } - - // a bit more complicated: could include a "empty reference" to outside concept - if (lax != null && lax.actionType == NodeLateActionLinkToReference.ActionType.SetDictionaryEntry - && lax.uanode != null - && this.packages != null) - { - // tracking - var foundAtAll = false; - - // 1st, take reference and turn it into Referable - var targetReferable = FindAllReferableByReference(this.packages, lax.targetReference); - if (targetReferable != null) - { - // 2nd, try to lookup the Referable and turn it into a uanode - var targetNodeRec = this.LookupNodeRecordFromReferable(targetReferable); - if (targetNodeRec != null && targetNodeRec.uanode != null) - { - // simple case: have a target node, just make a link - if (lax.uanode.ReferenceExists(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - targetNodeRec.uanode.NodeId)) - { - lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - targetNodeRec.uanode.NodeId); - } - foundAtAll = true; - } - } - - // make "empty reference"?? - // by definition, this makes only sense if the targetReference has exactly 1 key, as we could - // only have one key in a dictionary entry - if (!foundAtAll && lax.targetReference.Keys.Count == 1) - { - // can turn the targetReference to a simple identification - //var targetId = new AdminShellConverters().Identifier(lax.targetReference.Keys[0].Value); - var targetId = lax.targetReference.Keys[0].Value; - - // we might have such an (empty) target already available as uanode - var nr = this.LookupNodeRecordFromIdentification(targetId); - if (nr != null) - { - // just create the missing link - if (!lax.uanode.ReferenceExists(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - nr.uanode?.NodeId)) - { - lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - nr.uanode?.NodeId); - } - } - else - { - // create NEW empty reference? - if (this.RootMissingDictionaryEntries != null) - { - // create missing object - var miss = this.CreateAddObject( - this.RootMissingDictionaryEntries, - AasUaBaseEntity.CreateMode.Instance, - targetId, - ReferenceTypeIds.HasComponent, - this.AasTypes.ConceptDescription.GetTypeObjectFor(targetId)?.NodeId); - - // add the reference - if (lax.uanode.ReferenceExists(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - miss?.NodeId)) - { - lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - miss?.NodeId); - } - - // put it into the NodeRecords, that it can be re-used?? no!! - this.AddNodeRecord(new AasEntityBuilder.NodeRecord(miss, targetId)); - } - else - { - // just create the missing link - // TODO (MIHO, 2020-08-06): check, which namespace shall be used - var missingTarget = new ExpandedNodeId("" + targetId, 99); - lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, - missingTarget); - } - } - } - } - - } - } - - //// references - // - - // ReSharper disable once UnusedType.Global - public class AasReference : Opc.Ua.IReference - { - // private members - private NodeId referenceTypeId = null; - private bool isInverse = false; - private ExpandedNodeId targetId = null; - - // public getters for IReference - public NodeId ReferenceTypeId { get { return referenceTypeId; } } - public bool IsInverse { get { return isInverse; } } - public ExpandedNodeId TargetId { get { return targetId; } } - - public AasReference() - { - } - - public AasReference(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId) - { - this.referenceTypeId = referenceTypeId; - this.isInverse = isInverse; - this.targetId = targetId; - } - } - - //// Reference types - // - - public ReferenceTypeState CreateAddReferenceType( - string browseDisplayName, string inverseName, - uint preferredNumId = 0, bool useZeroNS = false, NodeId sourceId = null) - { - // create node itself - var x = new ReferenceTypeState(); - x.BrowseName = browseDisplayName; - x.DisplayName = browseDisplayName; - x.InverseName = inverseName; - x.Symmetric = false; - x.IsAbstract = false; - x.NodeId = nodeMgr.NewType(nodeMgr.SystemContext, AasUaBaseEntity.CreateMode.Type, x, preferredNumId); - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - - // set Subtype reference - if (sourceId == null) - sourceId = new NodeId(32, 0); - nodeMgr.AddExternalReferencePublic(sourceId, ReferenceTypeIds.HasSubtype, false, - x.NodeId, nodeMgrExternalReferences); - - // done - return x; - } - - //// Folders - // - - public FolderState CreateAddFolder(AasUaBaseEntity.CreateMode mode, - NodeState parent, string browseDisplayName) - { - var x = new FolderState(parent); - x.BrowseName = browseDisplayName; - x.DisplayName = browseDisplayName; - x.NodeId = nodeMgr.NewFromParent(nodeMgr.SystemContext, mode, x, parent); - x.TypeDefinitionId = ObjectTypeIds.FolderType; - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - if (parent != null) - parent.AddChild(x); - return x; - } - - //// DataTypes - // - - public DataTypeState CreateAddDataType( - string browseDisplayName, NodeId superTypeId, uint preferredNumId = 0) - { - var x = new DataTypeState(); - x.BrowseName = "" + browseDisplayName; - x.DisplayName = "" + browseDisplayName; - x.Description = new LocalizedText("en", browseDisplayName); - x.SuperTypeId = superTypeId; - x.NodeId = nodeMgr.NewType(nodeMgr.SystemContext, AasUaBaseEntity.CreateMode.Type, x, preferredNumId); - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - return x; - } - - //// Object types - // - - /// - /// Helper to create an ObjectType-Node and it to the information model. - /// - /// Name displayed in the node tree - /// Base class or similar - /// Numerical id of the node in the default name space to be set fixed - /// Lookup a Description on AAS literal/ refSemantics - /// Modeling Rule, if not None - public BaseObjectTypeState CreateAddObjectType( - string browseDisplayName, - NodeId superTypeId, - uint preferredNumId = 0, - string descriptionKey = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - var x = AasUaNodeHelper.CreateObjectType(browseDisplayName, superTypeId, descriptionKey: descriptionKey); - x.NodeId = nodeMgr.NewType(nodeMgr.SystemContext, AasUaBaseEntity.CreateMode.Type, - x, preferredNumId); - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - return x; - } - - //// Variable types - // - - public class AasVariableTypeState : BaseVariableTypeState - { - // ReSharper disable once EmptyConstructor - public AasVariableTypeState() - : base() - { } - } - - public AasVariableTypeState CreateAddVariableType(string browseDisplayName, NodeId superTypeId, - uint preferredNumId = 0) - { - var x = new AasVariableTypeState(); - x.BrowseName = "" + browseDisplayName; - x.DisplayName = "" + browseDisplayName; - x.Description = new LocalizedText("en", browseDisplayName); - x.SuperTypeId = superTypeId; - x.NodeId = nodeMgr.NewType(nodeMgr.SystemContext, AasUaBaseEntity.CreateMode.Type, - x, preferredNumId); - - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - return x; - } - - //// Objects - // - - /// - /// Helper to create an Object-Node. Note: __NO__ NodeId is created by the default! Must be done by outer - /// functionality!! - /// - /// Parent node - /// Type or instance - /// Name displayed in the node tree - /// - /// Type of the Object - /// Modeling Rule, if not None - /// - /// The node - public BaseObjectState CreateAddObject( - NodeState parent, AasUaBaseEntity.CreateMode mode, - string browseDisplayName, - NodeId referenceTypeFromParentId = null, - NodeId typeDefinitionId = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None, - string extraName = null) - { - var x = AasUaNodeHelper.CreateObject(parent, browseDisplayName, typeDefinitionId: typeDefinitionId, - modellingRule: modellingRule, extraName: extraName); - x.NodeId = nodeMgr.NewFromParent(nodeMgr.SystemContext, mode, x, parent); - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - if (parent != null) - parent.AddChild(x); - - if (referenceTypeFromParentId != null) - { - if (parent != null) - { - if (!parent.ReferenceExists(referenceTypeFromParentId, false, x.NodeId)) - parent.AddReference(referenceTypeFromParentId, false, x.NodeId); - if (referenceTypeFromParentId == ReferenceTypeIds.HasComponent) - x.AddReference(referenceTypeFromParentId, true, parent.NodeId); - if (referenceTypeFromParentId == ReferenceTypeIds.HasProperty) - x.AddReference(referenceTypeFromParentId, true, parent.NodeId); - } - - //// nodeMgr.AddReference(parentNodeId, new AasReference(referenceTypeId, false, x.NodeId)); - } - - //// if (typeDefinitionId != null) - //// { - //// x.TypeDefinitionId = typeDefinitionId; - //// x.AddReference(ReferenceTypeIds.HasTypeDefinition, false, typeDefinitionId); - //// // nodeMgr.AddReference(x.NodeId, new AasReference(ReferenceTypeIds.HasTypeDefinition, false, - //// // typeDefinitionId)); - //// } - - return x; - } - - //// Properties - // - - /// - /// Helper to create an PropertyState-Node for a certain type and add it to the information model. - /// Note: __NO__ NodeId is created by the default! Must be done by outer functionality!! - /// - /// C# type of the proprty - /// Parent node - /// Type or instance - /// Name displayed in the node tree - /// Data type, such as String.. Given by DataTypeIds... - /// Value of the type T or Null - /// - /// Type definition; independent from DataType! - /// -1 or e.g. 1 for array - /// Apply default settings for a normal Property - /// Modeling Rule, if not None - /// NodeState - public PropertyState CreateAddPropertyState( - NodeState parent, AasUaBaseEntity.CreateMode mode, - string browseDisplayName, - NodeId dataTypeId, T value, - NodeId referenceTypeFromParentId = null, - NodeId typeDefinitionId = null, - int valueRank = -2, - bool defaultSettings = false, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - // apply cumulative settings - if (defaultSettings) - { - referenceTypeFromParentId = ReferenceTypeIds.HasProperty; - typeDefinitionId = VariableTypeIds.PropertyType; - if (valueRank == -2) - valueRank = -1; - } - - // make Property - var x = new PropertyState(parent); - x.BrowseName = "" + browseDisplayName; - x.DisplayName = "" + browseDisplayName; - x.Description = new LocalizedText("en", browseDisplayName); - x.DataType = dataTypeId; - if (valueRank > -2) - x.ValueRank = valueRank; - // ReSharper disable once RedundantCast - x.Value = (T)value; - AasUaNodeHelper.CheckSetModellingRule(modellingRule, x); - x.NodeId = nodeMgr.NewFromParent(nodeMgr.SystemContext, mode, x, parent); - - // add Node - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, x); - if (parent != null) - parent.AddChild(x); - - // set relations - if (referenceTypeFromParentId != null) - { - if (parent != null) - { - if (!parent.ReferenceExists(referenceTypeFromParentId, false, x.NodeId)) - { - parent.AddReference(referenceTypeFromParentId, false, x.NodeId); - } - if (referenceTypeFromParentId == ReferenceTypeIds.HasComponent) - x.AddReference(referenceTypeFromParentId, true, parent.NodeId); - if (referenceTypeFromParentId == ReferenceTypeIds.HasProperty) - x.AddReference(referenceTypeFromParentId, true, parent.NodeId); - } - } - if (typeDefinitionId != null) - { - x.TypeDefinitionId = typeDefinitionId; - } - - x.AccessLevel = AccessLevels.CurrentReadOrWrite; - x.UserAccessLevel = AccessLevels.CurrentReadOrWrite; - - return x; - } - - public MethodState CreateAddMethodState( - NodeState parent, AasUaBaseEntity.CreateMode mode, - string browseDisplayName, - Argument[] inputArgs = null, Argument[] outputArgs = null, NodeId referenceTypeFromParentId = null, - NodeId methodDeclarationId = null, GenericMethodCalledEventHandler onCalled = null) - { - // method node - var m = new MethodState(parent); - m.BrowseName = "" + browseDisplayName; - m.DisplayName = "" + browseDisplayName; - m.Description = new LocalizedText("en", browseDisplayName); - m.NodeId = nodeMgr.NewFromParent(nodeMgr.SystemContext, mode, m, parent); - if (methodDeclarationId != null) - m.MethodDeclarationId = methodDeclarationId; - - m.Executable = true; - m.UserExecutable = true; - - nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, m); - if (parent != null) - parent.AddChild(m); - - if (referenceTypeFromParentId != null) - { - if (parent != null) - { - parent.AddReference(referenceTypeFromParentId, false, m.NodeId); - if (referenceTypeFromParentId == ReferenceTypeIds.HasComponent) - m.AddReference(referenceTypeFromParentId, true, parent.NodeId); - if (referenceTypeFromParentId == ReferenceTypeIds.HasProperty) - m.AddReference(referenceTypeFromParentId, true, parent.NodeId); - } - } - - // can have inputs, outputs - for (int i = 0; i < 2; i++) - { - // pretty argument list - var arguments = (i == 0) ? inputArgs : outputArgs; - if (arguments == null || arguments.Length < 1) - continue; - - // make a property for this - var prop = CreateAddPropertyState( - m, mode, - (i == 0) ? "InputArguments" : "OutputArguments", - DataTypeIds.Argument, - arguments, - ReferenceTypeIds.HasProperty, - typeDefinitionId: VariableTypeIds.PropertyType, - valueRank: 1); - - // explicitely add arguments ass well? - if (i == 0) - m.InputArguments = prop; - - if (i == 1) - m.OutputArguments = prop; - - } - - // event handler - if (onCalled != null) - m.OnCallMethod = onCalled; - - - return m; - } - - - //// Entities - // - - public class AasTypeEntities - { - public AasUaEntityPathType PathType; - public AasUaEntityMimeType MimeType; - - public AasUaEntityIdentification Identification; - public AasUaEntityAdministration Administration; - public AasUaEntityQualifier Qualifier; - public AasUaEntityAssetKind AssetKind; - public AasUaEntityModelingKind ModelingKind; - public AasUaEntityReferable Referable; - public AasUaEntityReferenceBase ReferenceBase; - public AasUaEntityReference Reference; - public AasUaEntitySemanticId SemanticId; - public AasUaEntitySubmodel Submodel; - public AasUaEntityProperty Property; - public AasUaEntityCollection Collection; - public AasUaEntitySubmodelElement SubmodelElement; - public AasUaEntitySubmodelWrapper SubmodelWrapper; - public AasUaEntityFile File; - public AasUaEntityFileType FileType; - public AasUaEntityBlob Blob; - public AasUaEntityReferenceElement ReferenceElement; - public AasUaEntityRelationshipElement RelationshipElement; - public AasUaEntityOperationVariable OperationVariable; - public AasUaEntityOperation Operation; - public AasUaEntityConceptDescription ConceptDescription; - public AasUaEntityAsset Asset; - public AasUaEntityAAS AAS; - - public AasUaEntityDataSpecification DataSpecification; - public AasUaEntityDataSpecificationIEC61360 DataSpecificationIEC61360; - - public AasUaInterfaceAASIdentifiableType IAASIdentifiableType; - public AasUaInterfaceAASReferableType IAASReferableType; - - public AasUaNamespaceZeroEntity BaseInterfaceType; - - public AasUaNamespaceZeroReference HasDictionaryEntry; - public AasUaReferenceHasAasReference HasAasReference; - public AasUaNamespaceZeroReference HasInterface; - public AasUaNamespaceZeroReference HasAddIn; - public AasUaNamespaceZeroEntity DictionaryEntryType; - public AasUaNamespaceZeroEntity UriDictionaryEntryType; - public AasUaNamespaceZeroEntity IrdiDictionaryEntryType; - public AasUaNamespaceZeroEntity DictionaryFolderType; - - public void BuildEntites(AasEntityBuilder builder) - { - // build up entities, which are in the UA specs, but not in this Stack - BaseInterfaceType = new AasUaNamespaceZeroEntity(builder, 17602); - HasDictionaryEntry = new AasUaNamespaceZeroReference(builder, 17597); - HasInterface = new AasUaNamespaceZeroReference(builder, 17603); - HasAddIn = new AasUaNamespaceZeroReference(builder, 17604); - DictionaryEntryType = new AasUaNamespaceZeroEntity(builder, 17589); - UriDictionaryEntryType = new AasUaNamespaceZeroEntity(builder, 17600); - IrdiDictionaryEntryType = new AasUaNamespaceZeroEntity(builder, 17598); - DictionaryFolderType = new AasUaNamespaceZeroEntity(builder, 17591); - - // AAS DataTypes - PathType = new AasUaEntityPathType(builder); - MimeType = new AasUaEntityMimeType(builder); - - // first entities - Referable = new AasUaEntityReferable(builder, 1004); - Identification = new AasUaEntityIdentification(builder, 1000); - Administration = new AasUaEntityAdministration(builder, 1001); - - // interfaces - IAASReferableType = new AasUaInterfaceAASReferableType( - builder, 2001); // dependencies: Referable - IAASIdentifiableType = new AasUaInterfaceAASIdentifiableType( - builder, 2000); // dependencies: IAASReferable - - // AAS References - ReferenceBase = new AasUaEntityReferenceBase(builder, 0); - Reference = new AasUaEntityReference(builder, 1005); - SemanticId = new AasUaEntitySemanticId(builder, 1006); // dependecies: Reference - HasAasReference = new AasUaReferenceHasAasReference(builder, 4000); // dependencies: Referable - - // Data Specifications - DataSpecification = new AasUaEntityDataSpecification(builder, 3000); - DataSpecificationIEC61360 = new AasUaEntityDataSpecificationIEC61360( - builder, 3001); // dependencies: Reference, Identification, Administration - - // rest - Qualifier = new AasUaEntityQualifier(builder, 1002); // dependencies: SemanticId, Reference - AssetKind = new AasUaEntityAssetKind(builder, 1025); - ModelingKind = new AasUaEntityModelingKind(builder, 1003); - SubmodelElement = new AasUaEntitySubmodelElement(builder, 1008); - SubmodelWrapper = new AasUaEntitySubmodelWrapper(builder, 1012); // dependencies: SubmodelElement - Submodel = new AasUaEntitySubmodel(builder, 1007); // dependencies: SubmodelWrapper - Property = new AasUaEntityProperty(builder, 1009); - Collection = new AasUaEntityCollection(builder, 1010); // needs 2 ids! - FileType = new AasUaEntityFileType(builder, 1014); - File = new AasUaEntityFile(builder, 1013); // dependencies: FileType - Blob = new AasUaEntityBlob(builder, 1015); - ReferenceElement = new AasUaEntityReferenceElement(builder, 1016); - RelationshipElement = new AasUaEntityRelationshipElement(builder, 1017); - OperationVariable = new AasUaEntityOperationVariable(builder, 1018); - Operation = new AasUaEntityOperation(builder, 1019); - //TODO:Remove - //ConceptDictionary = new AasUaEntityConceptDictionary(builder, 1020); - ConceptDescription = new AasUaEntityConceptDescription(builder, 1021); - //TODO:Remove - //View = new AasUaEntityView(builder, 1022); - Asset = new AasUaEntityAsset(builder, 1023); - AAS = new AasUaEntityAAS(builder, 1024); - } - } - - private AasTypeEntities aasTypes = null; - public AasTypeEntities AasTypes { get { return aasTypes; } } - - //// Annotations - // - - private Dictionary> nodeStateAnnotations = new Dictionary>(); - - public void AddNodeStateAnnotation(NodeState nodeState, object businessObject) - { - if (!nodeStateAnnotations.ContainsKey(nodeState)) - nodeStateAnnotations[nodeState] = new List(); - nodeStateAnnotations[nodeState].Add(businessObject); - } - - public void RemoveNodeStateAnnotation(NodeState nodeState, object businessObject) - { - if (!nodeStateAnnotations.ContainsKey(nodeState)) - return; - if (nodeStateAnnotations[nodeState].Contains(businessObject)) - nodeStateAnnotations[nodeState].Remove(businessObject); - } - - public T FindNoteStateAnnotation(NodeState nodeState) where T : class - { - if (nodeState == null) - return null; - if (!nodeStateAnnotations.ContainsKey(nodeState)) - return null; - foreach (var bo in nodeStateAnnotations[nodeState]) - if (bo is T) - return bo as T; - return null; - } - - } - -} diff --git a/src/AasxServerStandardBib/AasNodeManager.cs b/src/AasxServerStandardBib/AasNodeManager.cs deleted file mode 100644 index c1772f09d..000000000 --- a/src/AasxServerStandardBib/AasNodeManager.cs +++ /dev/null @@ -1,426 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using AdminShellNS; -using Opc.Ua; -using Opc.Ua.Sample; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; - -namespace AasOpcUaServer -{ - /// - /// A node manager the diagnostic information exposed by the server. - /// - public class AasModeManager : SampleNodeManager - { - private AdminShellPackageEnv[] thePackageEnv = null; - private AasxUaServerOptions theServerOptions = null; - - #region Constructors - /// - /// Initializes the node manager. - /// - public AasModeManager( - Opc.Ua.Server.IServerInternal server, - ApplicationConfiguration configuration, - AdminShellPackageEnv[] env, - AasxUaServerOptions serverOptions = null) - : - base(server) - { - thePackageEnv = env; - theServerOptions = serverOptions; - - List namespaceUris = new List(); - namespaceUris.Add("http://opcfoundation.org/UA/i4aas/"); - namespaceUris.Add("http://admin-shell.io/samples/i4aas/instance/"); - // ReSharper disable once VirtualMemberCallInConstructor - NamespaceUris = namespaceUris; - - m_typeNamespaceIndex = Server.NamespaceUris.GetIndexOrAppend(namespaceUris[0]); - m_namespaceIndex = Server.NamespaceUris.GetIndexOrAppend(namespaceUris[1]); - - m_lastUsedId = 0; - } - #endregion - - #region INodeIdFactory Members - /// - /// Creates the NodeId for the specified node. - /// - /// The context. - /// Type or instance - /// The node. - /// The new NodeId. - public NodeId New(ISystemContext context, AasUaBaseEntity.CreateMode mode, NodeState node) - { - if (mode == AasUaBaseEntity.CreateMode.Type) - { - uint id = Utils.IncrementIdentifier(ref m_lastUsedId); - return new NodeId(id, m_typeNamespaceIndex); - } - else - { - uint id = Utils.IncrementIdentifier(ref m_lastUsedId); - return new NodeId(id, m_namespaceIndex); - } - } - #endregion - - public NodeId NewFromParent(ISystemContext context, AasUaBaseEntity.CreateMode mode, NodeState node, NodeState parent) - { - // create known node ids from the full path in the AAS - // causes an exception if anything has more than one qualifier! - if (parent == null) - { - return new NodeId(node.BrowseName.Name, m_namespaceIndex); - } - if (node.BrowseName.Name == "Qualifier") - { - return New(context, mode, node); - } - else - { - return new NodeId(parent.NodeId.Identifier.ToString() + "." + node.BrowseName.Name, m_namespaceIndex); - } - } - - public NodeId NewType(ISystemContext context, AasUaBaseEntity.CreateMode mode, - NodeState node, uint preferredNumId = 0) - { - uint id = preferredNumId; - if (id == 0) - id = Utils.IncrementIdentifier(ref m_lastUsedTypeId); - // this is thought to be a BUG in the OPCF code - //// return new NodeId(preferredNumId, m_typeNamespaceIndex); - if (mode == AasUaBaseEntity.CreateMode.Type) - return new NodeId(id, m_typeNamespaceIndex); - else - return new NodeId(id, m_namespaceIndex); - } - - public void SaveNodestateCollectionAsNodeSet2(ISystemContext context, NodeStateCollection nsc, Stream stream, - bool filterSingleNodeIds) - { - Opc.Ua.Export.UANodeSet nodeSet = new Opc.Ua.Export.UANodeSet(); - nodeSet.LastModified = DateTime.UtcNow; - nodeSet.LastModifiedSpecified = true; - - foreach (var n in nsc) - nodeSet.Export(context, n); - - if (filterSingleNodeIds) - { - // MIHO: There might be DOUBLE nodeIds in the the set!!!!!!!!!! WTF!!!!!!!!!!!!! - // Brutally eliminate them - var nodup = new List(); - foreach (var it in nodeSet.Items) - { - var found = false; - foreach (var it2 in nodup) - if (it.NodeId == it2.NodeId) - found = true; - if (found) - continue; - nodup.Add(it); - } - nodeSet.Items = nodup.ToArray(); - } - - nodeSet.Write(stream); - } - - #region INodeManager Members - /// - /// Does any initialization required before the address space can be used. - /// - /// - /// The externalReferences is an out parameter that allows the node manager to link to nodes - /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and - /// should have a reference to the root folder node(s) exposed by this node manager. - /// - public override void CreateAddressSpace(IDictionary> externalReferences) - { - lock (Lock) - { - base.CreateAddressSpace(externalReferences); - - // Note: might be helpful for debugging - //// var env = new AdminShell.PackageEnv("Festo-USB-stick-sample-admin-shell.aasx"); - - if (true) - { - var builder = new AasEntityBuilder(this, thePackageEnv, null, this.theServerOptions); - - // Root of whole structure is special, needs to link to external reference - builder.RootAAS = builder.CreateAddFolder(AasUaBaseEntity.CreateMode.Instance, null, "AASROOT"); - // Note: this is TOTALLY WEIRD, but it establishes an inverse reference .. somehow - this.AddExternalReferencePublic(new NodeId(85, 0), ReferenceTypeIds.Organizes, false, - builder.RootAAS.NodeId, externalReferences); - this.AddExternalReferencePublic(builder.RootAAS.NodeId, ReferenceTypeIds.Organizes, true, - new NodeId(85, 0), externalReferences); - - - // Folders for DataSpecs - // DO NOT USE THIS FEATURE -> Data Spec are "under" the CDs - //// builder.RootDataSpecifications = builder.CreateAddFolder( - //// builder.RootAAS, "DataSpecifications"); - //// builder.RootDataSpecifications = builder.CreateAddObject( - //// builder.RootAAS, "DataSpecifications"); - - if (false) - // ReSharper disable once HeuristicUnreachableCode -#pragma warning disable 162 - { - // Folders for Concept Descriptions - // ReSharper disable once HeuristicUnreachableCode - builder.RootConceptDescriptions = builder.CreateAddFolder( - AasUaBaseEntity.CreateMode.Instance, - builder.RootAAS, "ConceptDescriptions"); - - // create missing dictionary entries - builder.RootMissingDictionaryEntries = builder.CreateAddFolder( - AasUaBaseEntity.CreateMode.Instance, - builder.RootAAS, "DictionaryEntries"); - } -#pragma warning restore 162 - else - { - // create folder(s) under root - var topOfDict = builder.CreateAddObject(null, - AasOpcUaServer.AasUaBaseEntity.CreateMode.Instance, "Dictionaries", - referenceTypeFromParentId: null, - typeDefinitionId: builder.AasTypes.DictionaryFolderType.GetTypeNodeId()); - // Note: this is TOTALLY WEIRD, but it establishes an inverse reference .. somehow - // 2253 = Objects? - this.AddExternalReferencePublic(new NodeId(2253, 0), - ReferenceTypeIds.HasComponent, false, topOfDict.NodeId, externalReferences); - this.AddExternalReferencePublic(topOfDict.NodeId, - ReferenceTypeIds.HasComponent, true, new NodeId(2253, 0), externalReferences); - - // now, create a dictionary under .. - // Folders for Concept Descriptions - builder.RootConceptDescriptions = builder.CreateAddObject(topOfDict, - AasOpcUaServer.AasUaBaseEntity.CreateMode.Instance, "ConceptDescriptions", - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - typeDefinitionId: builder.AasTypes.DictionaryFolderType.GetTypeNodeId()); - - // create missing dictionary entries - builder.RootMissingDictionaryEntries = builder.CreateAddObject(topOfDict, - AasOpcUaServer.AasUaBaseEntity.CreateMode.Instance, "DictionaryEntries", - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - typeDefinitionId: builder.AasTypes.DictionaryFolderType.GetTypeNodeId()); - } - - // start process - foreach (var ee in thePackageEnv) - { - if (ee != null) - builder.CreateAddInstanceObjects(ee.AasEnv); - } - } - - // Try: ensure the reverse refernces exist. - //// AddReverseReferences(externalReferences); - - if (theServerOptions != null - && theServerOptions.SpecialJob == AasxUaServerOptions.JobType.ExportNodesetXml) - { - try - { - // empty list - var nodesToExport = new NodeStateCollection(); - - // apply filter criteria - foreach (var y in this.PredefinedNodes) - { - var node = y.Value; - if (theServerOptions.ExportFilterNamespaceIndex != null - && !theServerOptions.ExportFilterNamespaceIndex.Contains(node.NodeId.NamespaceIndex)) - continue; - nodesToExport.Add(node); - } - - // export - Utils.Trace("Writing export file: " + theServerOptions.ExportFilename); - var stream = new StreamWriter(theServerOptions.ExportFilename); - - //// nodesToExport.SaveAsNodeSet2(this.SystemContext, stream.BaseStream, null, - //// theServerOptions != null && theServerOptions.FilterForSingleNodeIds); - - //// nodesToExport.SaveAsNodeSet2(this.SystemContext, stream.BaseStream); - SaveNodestateCollectionAsNodeSet2(this.SystemContext, nodesToExport, stream.BaseStream, - theServerOptions != null && theServerOptions.FilterForSingleNodeIds); - - try - { - stream.Close(); - } - catch (Exception ex) - { - AdminShellNS.LogInternally.That.SilentlyIgnoredError(ex); - } - - // stop afterwards - if (theServerOptions.FinalizeAction != null) - { - Utils.Trace("Requesting to shut down application.."); - theServerOptions.FinalizeAction(); - } - - } - catch (Exception ex) - { - Utils.Trace(ex, "When exporting to {0}", "" + theServerOptions.ExportFilename); - } - - // shutdown .. - - } - - Debug.WriteLine("Done creating custom address space!"); - Utils.Trace("Done creating custom address space!"); - } - } - - public NodeStateCollection GenerateInjectNodeStates() - { - // new list - var res = new NodeStateCollection(); - - // Missing Object Types - res.Add(AasUaNodeHelper.CreateObjectType("BaseInterfaceType", - ObjectTypeIds.BaseObjectType, new NodeId(17602, 0))); - res.Add(AasUaNodeHelper.CreateObjectType("DictionaryFolderType", - ObjectTypeIds.FolderType, new NodeId(17591, 0))); - res.Add(AasUaNodeHelper.CreateObjectType("DictionaryEntryType", - ObjectTypeIds.BaseObjectType, new NodeId(17589, 0))); - res.Add(AasUaNodeHelper.CreateObjectType("UriDictionaryEntryType", - new NodeId(17589, 0), new NodeId(17600, 0))); - res.Add(AasUaNodeHelper.CreateObjectType("IrdiDictionaryEntryType", - new NodeId(17589, 0), new NodeId(17598, 0))); - - // Missing Reference Types - res.Add(AasUaNodeHelper.CreateReferenceType("HasDictionaryEntry", "DictionaryEntryOf", - ReferenceTypeIds.NonHierarchicalReferences, new NodeId(17597, 0))); - res.Add(AasUaNodeHelper.CreateReferenceType("HasInterface", "InterfaceOf", - ReferenceTypeIds.NonHierarchicalReferences, new NodeId(17603, 0))); - res.Add(AasUaNodeHelper.CreateReferenceType("HasAddIn", "AddInOf", - ReferenceTypeIds.HasComponent, new NodeId(17604, 0))); - - // deliver list - return res; - } - - public void AddReference(NodeId node, Opc.Ua.IReference reference) - { - var dict = new Dictionary>(); - // ReSharper disable once RedundantExplicitArrayCreation - dict.Add(node, new List(new Opc.Ua.IReference[] { reference })); - this.AddReferences(dict); - } - - /// - /// Loads a node set from a file or resource and addes them to the set of predefined nodes. - /// - protected override NodeStateCollection LoadPredefinedNodes(ISystemContext context) - { - NodeStateCollection predefinedNodes = new NodeStateCollection(); - return predefinedNodes; - } - - /// - /// Replaces the generic node with a node specific to the model. - /// - protected override NodeState AddBehaviourToPredefinedNode(ISystemContext context, NodeState predefinedNode) - { - return predefinedNode; - } - - /// - /// Does any processing after a monitored item is created. - /// - protected override void OnCreateMonitoredItem( - ISystemContext systemContext, - MonitoredItemCreateRequest itemToCreate, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem) - { - // TBD - } - - /// - /// Does any processing after a monitored item is created. - /// - protected override void OnModifyMonitoredItem( - ISystemContext systemContext, - MonitoredItemModifyRequest itemToModify, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem, - double previousSamplingInterval) - { - // TBD - } - - /// - /// Does any processing after a monitored item is deleted. - /// - protected override void OnDeleteMonitoredItem( - ISystemContext systemContext, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem) - { - // TBD - } - - /// - /// Does any processing after a monitored item is created. - /// - protected override void OnSetMonitoringMode( - ISystemContext systemContext, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem, - MonitoringMode previousMode, - MonitoringMode currentMode) - { - // TBD - } - #endregion - - #region Private Fields - private ushort m_namespaceIndex; - private ushort m_typeNamespaceIndex; - private long m_lastUsedId; - private long m_lastUsedTypeId; - #endregion - } -} diff --git a/src/AasxServerStandardBib/AasUaEntities.cs b/src/AasxServerStandardBib/AasUaEntities.cs deleted file mode 100644 index 814b5acd2..000000000 --- a/src/AasxServerStandardBib/AasUaEntities.cs +++ /dev/null @@ -1,1984 +0,0 @@ -/* -Copyright (c) 2018-2019 Festo AG & Co. KG -Author: Michael Hoffmeister - -This source code is licensed under the Apache License 2.0 (see LICENSE.txt). - -This source code may use other Open Source software components (see LICENSE.txt). -*/ - - -using Extensions; -using Opc.Ua; -using System; -using System.Collections.Generic; -using System.Globalization; -using AAS = AasCore.Aas3_0; - -// TODO (MIHO, 2020-08-29): The UA mapping needs to be overworked in order to comply the joint aligment with I4AAS -// TODO (MIHO, 2020-08-29): The UA mapping needs to be checked for the "new" HasDataSpecification strcuture of V2.0.1 - -namespace AasOpcUaServer -{ - public class AasUaBaseEntity - { - public enum CreateMode { Type, Instance }; - - /// - /// Reference back to the entity builder - /// - protected AasEntityBuilder entityBuilder = null; - - public AasUaBaseEntity(AasEntityBuilder entityBuilder) - { - this.entityBuilder = entityBuilder; - } - - /// - /// Typically the node of the entity in the AAS type object space - /// - protected NodeState typeObject = null; - - /// - /// If the entitiy does not have a direct type object, the object id instead (for pre-defined objects) - /// - protected NodeId typeObjectId = null; - - /// - /// Getter of the type object - /// - public NodeState GetTypeObject() - { - return typeObject; - } - - /// - /// Getter of the type object id, either directly or via the type object (if avilable) - /// - /// - public NodeId GetTypeNodeId() - { - if (typeObjectId != null) - return typeObjectId; - if (typeObject == null) - return null; - return typeObject.NodeId; - } - } - - public class AasUaEntityPathType : AasUaBaseEntity - { - public AasUaEntityPathType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type elements - this.typeObject = this.entityBuilder.CreateAddDataType("AASPathType", DataTypeIds.String); - } - } - - public class AasUaEntityMimeType : AasUaBaseEntity - { - public AasUaEntityMimeType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type elements - this.typeObject = this.entityBuilder.CreateAddDataType("AASMimeType", DataTypeIds.String); - } - } - - public class AasUaEntityIdentification : AasUaBaseEntity - { - public AasUaEntityIdentification(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASIdentifierType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Identifier"); - // add some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "IdType", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Id", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, - string identification = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, mode, "Identification", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - if (identification != null) - { - //this.entityBuilder.CreateAddPropertyState(o, mode, "IdType", - // DataTypeIds.String, "" + "" + identification.IdType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, mode, "Id", - DataTypeIds.String, "" + "" + identification, defaultSettings: true); - } - } - - return o; - } - } - - public class AasUaEntityAdministration : AasUaBaseEntity - { - public AasUaEntityAdministration(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAdministrativeInformationType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:AdministrativeInformation"); - // add some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Version", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Revision", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, - IAdministrativeInformation administration = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && administration == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, mode, "Administration", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - if (administration == null) - return null; - this.entityBuilder.CreateAddPropertyState(o, mode, "Version", - DataTypeIds.String, "" + "" + administration.Version, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, mode, "Revision", - DataTypeIds.String, "" + "" + administration.Revision, defaultSettings: true); - } - - return o; - } - } - - public class AasUaEntityQualifier : AasUaBaseEntity - { - public AasUaEntityQualifier(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASQualifierType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, "AAS:Qualifier"); - - // add some elements - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, - CreateMode.Type, null, "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Type", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Value", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, - null, "ValueId", AasUaNodeHelper.ModellingRule.Optional); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, IQualifier qualifier = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && qualifier == null) - return null; - - if (mode == CreateMode.Type) - { - // plain - var o = this.entityBuilder.CreateAddObject(parent, mode, "Qualifier", ReferenceTypeIds.HasComponent, - GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - // need data - if (qualifier == null) - return null; - - // do a little extra? - string extraName = null; - if (qualifier.Type != null && qualifier.Type.Length > 0) - { - extraName = "Qualifier:" + qualifier.Type; - if (qualifier.Value != null && qualifier.Value.Length > 0) - extraName += "=" + qualifier.Value; - } - - var o = this.entityBuilder.CreateAddObject(parent, mode, "Qualifier", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule, - extraName: extraName); - - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(o, - CreateMode.Instance, qualifier.SemanticId, "SemanticId"); - this.entityBuilder.CreateAddPropertyState(o, mode, "Type", - DataTypeIds.String, "" + qualifier.Type, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.String, "" + qualifier.Value, defaultSettings: true); - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, - CreateMode.Instance, qualifier.ValueId, "ValueId"); - - return o; - } - - } - } - - public class AasUaEntityAssetKind : AasUaBaseEntity - { - public AasUaEntityAssetKind(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // no special type here (is a string) - } - - //public NodeState CreateAddElements(NodeState parent, CreateMode mode, AssetKind kind = null, - // TODO (jtikekar, 2023-09-04): What should be the default of AssetKind - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AssetKind kind = AssetKind.Type, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (mode == CreateMode.Instance) - return null; - - var o = this.entityBuilder.CreateAddPropertyState(parent, mode, "Kind", - DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + kind, defaultSettings: true, - modellingRule: modellingRule); - - return o; - } - } - - public class AasUaEntityModelingKind : AasUaBaseEntity - { - public AasUaEntityModelingKind(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // no special type here (is a string) - } - - //public NodeState CreateAddElements(NodeState parent, CreateMode mode, ModelingKind kind = null, - // TODO (jtikekar, 2023-09-04): default value of ModellingKind - public NodeState CreateAddElements(NodeState parent, CreateMode mode, ModellingKind kind = ModellingKind.Template, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (mode == CreateMode.Instance) - return null; - - var o = this.entityBuilder.CreateAddPropertyState(parent, mode, "Kind", - DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + kind, defaultSettings: true, - modellingRule: modellingRule); - - return o; - } - } - - public class AasUaEntityReferable : AasUaBaseEntity - { - public AasUaEntityReferable(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // NO type object required - // see IAASReferable interface - } - - /// - /// This adds all Referable attributes to the parent and re-defines the descriptons - /// - public NodeState CreateAddElements(NodeState parent, CreateMode mode, IReferable refdata = null) - { - if (parent == null) - return null; - if (mode == CreateMode.Instance && refdata == null) - return null; - - if (mode == CreateMode.Type || refdata?.Category != null) - this.entityBuilder.CreateAddPropertyState(parent, mode, "Category", - DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + refdata?.Category, - defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - // No idShort as typically in the DisplayName of the node - - if (mode == CreateMode.Instance) - { - // now, re-set the description on the parent - // ISSUE: only ONE language supported! - parent.Description = AasUaUtils.GetBestUaDescriptionFromAasDescription(refdata?.Description); - } - - return null; - } - } - - public class AasUaEntityReferenceBase : AasUaBaseEntity - { - public AasUaEntityReferenceBase(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // nothing, only used to share code - } - - /// - /// Sets the "Keys" value information of an AAS Reference. This is especially important for referencing - /// outwards of the AAS (environment). - /// - public void CreateAddKeyElements(NodeState parent, CreateMode mode, List keys = null) - { - if (parent == null) - return; - - // MIHO: open62541 does not to process Values as string[], therefore change it temporarily - - if (this.entityBuilder != null && this.entityBuilder.theServerOptions != null - && this.entityBuilder.theServerOptions.ReferenceKeysAsSingleString) - { - // fix for open62541 - var keyo = this.entityBuilder.CreateAddPropertyState(parent, mode, "Values", - DataTypeIds.String, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - Reference newRef = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, keys); - keyo.Value = AasUaUtils.ToOpcUaReference(newRef); - } - } - else - { - // default behaviour - var keyo = this.entityBuilder?.CreateAddPropertyState(parent, mode, "Values", - DataTypeIds.Structure, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - Reference newRef = new Reference(AasCore.Aas3_0.ReferenceTypes.ModelReference, keys); - keyo.Value = AasUaUtils.ToOpcUaReferenceList(newRef)?.ToArray(); - } - } - } - - /// - /// Sets the "Keys" value information of an AAS Reference. This is especially important for referencing - /// outwards of the AAS (environment). - /// - public void CreateAddKeyElements(NodeState parent, CreateMode mode, List ids = null) - { - List keys = new List(); - if (parent == null) - return; - - // MIHO: open62541 does not to process Values as string[], therefore change it temporarily - - if (ids != null) - { - foreach (var id in ids) - { - var key = new Key(KeyTypes.GlobalReference, id.Id); - keys.Add(key); - } - } - - if (this.entityBuilder != null && this.entityBuilder.theServerOptions != null - && this.entityBuilder.theServerOptions.ReferenceKeysAsSingleString) - { - // fix for open62541 - var keyo = this.entityBuilder.CreateAddPropertyState(parent, mode, "Values", - DataTypeIds.String, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - Reference newRef = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, keys); - keyo.Value = AasUaUtils.ToOpcUaReference(newRef); - } - } - else - { - // default behaviour - var keyo = this.entityBuilder?.CreateAddPropertyState(parent, mode, "Values", - DataTypeIds.Structure, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - Reference newRef = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, keys); - keyo.Value = AasUaUtils.ToOpcUaReferenceList(newRef)?.ToArray(); - } - } - } - - /// - /// Sets the UA relation of an AAS Reference. This is especially important for reference within an AAS node - /// structure, to be - /// in the style of OPC UA - /// - public void CreateAddReferenceElements(NodeState parent, CreateMode mode, List keys = null) - { - if (parent == null) - return; - - if (mode == CreateMode.Type) - { - // makes no sense - } - else - { - // would make sense, but is replaced by the code in "CreateAddInstanceObjects" directly. - } - } - } - - public class AasUaEntityReference : AasUaEntityReferenceBase - { - public AasUaEntityReference(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASReferenceType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId); - // with some elements - this.CreateAddKeyElements(this.typeObject, CreateMode.Type, keys: null); - this.CreateAddReferenceElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, - AAS.IReference reference, string browseDisplayName = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - var o = this.entityBuilder.CreateAddObject(parent, mode, browseDisplayName ?? "Reference", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - if (reference == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, mode, browseDisplayName ?? "Reference", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // explicit strings? - if (reference is Reference modrf) - { - this.CreateAddKeyElements(o, mode, modrf.Keys); - - // find a matching concept description or other referable? - // as we do not have all other nodes realized, store a late action - this.entityBuilder.AddNodeLateAction( - new AasEntityBuilder.NodeLateActionLinkToReference( - o, - modrf, - AasEntityBuilder.NodeLateActionLinkToReference.ActionType.SetAasReference - )); - } - - if (reference is Reference glbrf) - { - this.CreateAddKeyElements(o, mode, glbrf.Keys); - - // find a matching concept description or other referable? - // as we do not have all other nodes realized, store a late action - this.entityBuilder.AddNodeLateAction( - new AasEntityBuilder.NodeLateActionLinkToReference( - o, - new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, glbrf.Keys), - AasEntityBuilder.NodeLateActionLinkToReference.ActionType.SetAasReference - )); - } - - // OK - return o; - } - } - } - - public class AasUaEntitySemanticId : AasUaEntityReferenceBase - { - public AasUaEntitySemanticId(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // re-use AASReferenceType for this - this.typeObject = this.entityBuilder.AasTypes.Reference.GetTypeObject(); - // with some elements - this.CreateAddReferenceElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddInstanceObject(NodeState parent, CreateMode mode, - AAS.IReference semid = null, string browseDisplayName = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - var o = this.entityBuilder.CreateAddObject(parent, mode, browseDisplayName ?? "SemanticId", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - if (semid == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, mode, browseDisplayName ?? "SemanticId", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // explicit strings? - this.CreateAddKeyElements(o, mode, semid.Keys); - - // find a matching concept description or other referable? - // as we do not have all other nodes realized, store a late action - this.entityBuilder.AddNodeLateAction( - new AasEntityBuilder.NodeLateActionLinkToReference( - parent, - //Reference.CreateNew(Key.ConceptDescription, semid?.Keys), - new Reference(AasCore.Aas3_0.ReferenceTypes.ModelReference, semid?.Keys), - AasEntityBuilder.NodeLateActionLinkToReference.ActionType.SetDictionaryEntry - )); - - // OK - return o; - } - } - } - - public class AasUaEntityAsset : AasUaBaseEntity - { - public AasUaEntityAsset(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAssetType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Asset"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add necessary type information - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.AssetKind.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.AssetKind.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, - null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, - null, "AssetIdentificationModel", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, IAssetInformation asset = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && asset == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, mode, "Asset", ReferenceTypeIds.HasComponent, - GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - // access - if (asset == null) - return null; - - // register node record - - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, asset?.GlobalAssetId)); - - // Referable - //this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, asset); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements( - o, CreateMode.Instance, asset?.GlobalAssetId); - //this.entityBuilder.AasTypes.Administration.CreateAddElements( - // o, CreateMode.Instance, asset.administration); - // HasKind - this.entityBuilder.AasTypes.AssetKind.CreateAddElements(o, CreateMode.Instance, asset.AssetKind); - // HasDataSpecification - //if (asset.hasDataSpecification != null && asset.hasDataSpecification != null) - // foreach (var ds in asset.hasDataSpecification) - // this.entityBuilder.AasTypes.Reference.CreateAddElements( - // o, CreateMode.Instance, ds?.dataSpecification, "DataSpecification"); - //// own attributes - //this.entityBuilder.AasTypes.Reference.CreateAddElements( - // o, CreateMode.Instance, asset.assetIdentificationModelRef, "AssetIdentificationModel"); - } - - return o; - } - } - - public class AasUaEntityAAS : AasUaBaseEntity - { - public AasUaEntityAAS(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAssetAdministrationShellType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:AssetAdministrationShell"); - - // interface - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add necessary type information - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "DerivedFrom", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // assets - this.entityBuilder.AasTypes.Asset.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // associated views - //this.entityBuilder.AasTypes.View.CreateAddElements(this.typeObject, CreateMode.Type, - // modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // associated submodels - this.entityBuilder.AasTypes.Submodel.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // concept dictionary - //this.entityBuilder.AasTypes.ConceptDictionary.CreateAddElements(this.typeObject, CreateMode.Type, - // modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddInstanceObject(NodeState parent, - AasCore.Aas3_0.Environment env, IAssetAdministrationShell aas) - { - // access - if (env == null || aas == null) - return null; - - // containing element - string extraName = null; - string browseName = "AssetAdministrationShell"; - if (aas.IdShort != null && aas.IdShort.Trim().Length > 0) - { - extraName = "AssetAdministrationShell:" + aas.IdShort; - browseName = aas.IdShort; - } - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, - browseName, ReferenceTypeIds.HasComponent, - GetTypeObject().NodeId, extraName: extraName); - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, aas)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, aas); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements( - o, CreateMode.Instance, aas.Id); - this.entityBuilder.AasTypes.Administration.CreateAddElements( - o, CreateMode.Instance, aas.Administration); - // HasDataSpecification - if (aas.EmbeddedDataSpecifications != null && aas.EmbeddedDataSpecifications != null) - foreach (var ds in aas.EmbeddedDataSpecifications) - this.entityBuilder.AasTypes.Reference.CreateAddElements( - o, CreateMode.Instance, ds.DataSpecification, "DataSpecification"); - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements( - o, CreateMode.Instance, aas.DerivedFrom, "DerivedFrom"); - - // associated asset - if (aas.AssetInformation != null) - { - this.entityBuilder.AasTypes.Asset.CreateAddElements(o, CreateMode.Instance, aas.AssetInformation); - } - - //// associated views - //if (aas.views != null) - // foreach (var vw in aas.views.views) - // this.entityBuilder.AasTypes.View.CreateAddElements( - // o, CreateMode.Instance, vw); - - // associated submodels - if (aas.Submodels != null && aas.Submodels.Count > 0) - foreach (var smr in aas.Submodels) - { - var sm = env.FindSubmodel(smr); - if (sm != null) - this.entityBuilder.AasTypes.Submodel.CreateAddElements( - o, CreateMode.Instance, sm); - } - - // make up CD dictionaries - //if (aas.conceptDictionaries != null && aas.conceptDictionaries.Count > 0) - //{ - // // ReSharper disable once UnusedVariable - // foreach (var cdd in aas.conceptDictionaries) - // { - // // TODO (MIHO, 2020-08-06): check (again) if reference to CDs is done are shall be done - // // here. They are stored separately. - // } - //} - - // results - return o; - } - } - - public class AasUaEntitySubmodel : AasUaBaseEntity - { - public AasUaEntitySubmodel(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Submodel"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add some elements - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, - "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // Qualifiable - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // SubmodelElements - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, ISubmodel sm = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - // create only containing element with generic name - var o = this.entityBuilder.CreateAddObject(parent, mode, "Submodel", ReferenceTypeIds.HasComponent, - this.GetTypeNodeId(), modellingRule: modellingRule); - return o; - } - else - { - // access - if (sm == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, mode, - "" + sm.IdShort, ReferenceTypeIds.HasComponent, - GetTypeObject().NodeId, extraName: "Submodel:" + sm.IdShort); - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, sm)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements( - o, CreateMode.Instance, sm); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements( - o, CreateMode.Instance, sm.Id); - this.entityBuilder.AasTypes.Administration.CreateAddElements( - o, CreateMode.Instance, sm.Administration); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject( - o, CreateMode.Instance, sm.SemanticId, "SemanticId"); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements( - o, CreateMode.Instance, (ModellingKind)sm.Kind); - // HasDataSpecification - if (sm.EmbeddedDataSpecifications != null && sm.EmbeddedDataSpecifications != null) - foreach (var ds in sm.EmbeddedDataSpecifications) - this.entityBuilder.AasTypes.Reference.CreateAddElements( - o, CreateMode.Instance, ds.DataSpecification, "DataSpecification"); - // Qualifiable - if (sm.Qualifiers != null) - foreach (var q in sm.Qualifiers) - this.entityBuilder.AasTypes.Qualifier.CreateAddElements( - o, CreateMode.Instance, q); - - // SubmodelElements - if (sm.SubmodelElements != null) - foreach (var smw in sm.SubmodelElements) - if (smw != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements( - o, CreateMode.Instance, smw); - - // result - return o; - } - } - } - - /// - /// This class is for the representation if SME in UA namespace - /// - public class AasUaEntitySubmodelElement : AasUaBaseEntity - { - public AasUaEntitySubmodelElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelElementType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:SubmodelElement"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId()); - - // add some elements to the type - // Note: in this special case, the instance elements are populated by AasUaEntitySubmodelElementBase, - // while the elements - // for the type are populated here - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, - "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // Qualifiable - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - } - - /// - /// This class is the base class of derived properties - /// - public class AasUaEntitySubmodelElementBase : AasUaBaseEntity - { - public AasUaEntitySubmodelElementBase(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // do NOT create type object, as this is done by sub-class - } - - public NodeState PopulateInstanceObject(NodeState o, ISubmodelElement sme) - { - // access - if (o == null || sme == null) - return null; - - // take this as perfect opportunity to register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, sme)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements( - o, CreateMode.Instance, sme); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject( - o, CreateMode.Instance, sme.SemanticId, "SemanticId"); - // HasDataSpecification - if (sme.EmbeddedDataSpecifications != null && sme.EmbeddedDataSpecifications != null) - foreach (var ds in sme.EmbeddedDataSpecifications) - this.entityBuilder.AasTypes.Reference.CreateAddElements( - o, CreateMode.Instance, ds.DataSpecification, "DataSpecification"); - // Qualifiable - if (sme.Qualifiers != null) - foreach (var q in sme.Qualifiers) - this.entityBuilder.AasTypes.Qualifier.CreateAddElements( - o, CreateMode.Instance, q); - - // result - return o; - } - } - - /// - /// This class will automatically instantiate the correct SubmodelElement entity. - /// - public class AasUaEntitySubmodelWrapper : AasUaBaseEntity - { - public AasUaEntitySubmodelWrapper(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // do NOT create type object, as this is done by sub-class - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, - ISubmodelElement smw = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - // access - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - // create only containing element (base type) with generic name - var o = this.entityBuilder.CreateAddObject(parent, mode, - "SubmodelElement", ReferenceTypeIds.HasComponent, - this.entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), modellingRule: modellingRule); - return o; - } - else - { - if (smw == null) - return null; - - if (smw is SubmodelElementCollection) - { - var coll = smw as SubmodelElementCollection; - return this.entityBuilder.AasTypes.Collection.CreateAddInstanceObject(parent, coll); - } - else if (smw is Property) - return this.entityBuilder.AasTypes.Property.CreateAddInstanceObject( - parent, smw as Property); - else if (smw is File) - return this.entityBuilder.AasTypes.File.CreateAddInstanceObject( - parent, smw as File); - else if (smw is Blob) - return this.entityBuilder.AasTypes.Blob.CreateAddInstanceObject( - parent, smw as Blob); - else if (smw is ReferenceElement) - return this.entityBuilder.AasTypes.ReferenceElement.CreateAddInstanceObject( - parent, smw as ReferenceElement); - else if (smw is RelationshipElement) - return this.entityBuilder.AasTypes.RelationshipElement.CreateAddInstanceObject( - parent, smw as RelationshipElement); - else if (smw is Operation) - return this.entityBuilder.AasTypes.Operation.CreateAddInstanceObject( - parent, smw as Operation); - - // nope - return null; - } - } - } - - public class AasUaEntityProperty : AasUaEntitySubmodelElementBase - { - public AasUaEntityProperty(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType( - "AASPropertyType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:Property"); - - // elements not in the base type - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Instance, null, - "ValueId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "ValueType", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Value", - DataTypeIds.BaseDataType, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, Property prop) - { - // access - if (prop == null) - return null; - - // for all - var mode = CreateMode.Instance; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, mode, "" + prop.IdShort, ReferenceTypeIds.HasComponent, - GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, prop); - - // TODO (MIHO, 2020-08-06): not sure if to add these - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, prop.ValueId, "ValueId"); - this.entityBuilder.CreateAddPropertyState(o, mode, "ValueType", - DataTypeIds.String, "" + prop.ValueType, defaultSettings: true); - - // aim is to support many types natively - var vt = prop.ValueType; - if (prop.ValueType == DataTypeDefXsd.Boolean) - { - var x = (prop.Value ?? "").ToLower().Trim(); - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Boolean, x == "true", defaultSettings: true); - } - else if (vt == DataTypeDefXsd.DateTime || vt == DataTypeDefXsd.Date || vt == DataTypeDefXsd.Time) - { - if (DateTime.TryParse(prop.Value, CultureInfo.InvariantCulture, - DateTimeStyles.AssumeUniversal, out var dt)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.DateTime, dt.ToFileTimeUtc(), defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Decimal || vt == DataTypeDefXsd.Integer || vt == DataTypeDefXsd.Long - || vt == DataTypeDefXsd.NonPositiveInteger || vt == DataTypeDefXsd.NegativeInteger) - { - if (Int64.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Int64, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Int) - { - if (Int32.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Int32, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Short) - { - if (Int16.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Int16, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Byte) - { - if (SByte.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Byte, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.NonNegativeInteger || vt == DataTypeDefXsd.PositiveInteger || vt == DataTypeDefXsd.UnsignedLong) - { - if (UInt64.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.UInt64, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.UnsignedInt) - { - if (UInt32.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.UInt32, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.UnsignedShort) - { - if (UInt16.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.UInt16, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.UnsignedByte) - { - if (Byte.TryParse(prop.Value, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Byte, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Double) - { - if (double.TryParse(prop.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Double, v, defaultSettings: true); - } - else if (vt == DataTypeDefXsd.Float) - { - if (float.TryParse(prop.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var v)) - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.Float, v, defaultSettings: true); - } - else - { - // leave in string - this.entityBuilder.CreateAddPropertyState(o, mode, "Value", - DataTypeIds.String, prop.Value, defaultSettings: true); - } - - // result - return o; - } - } - - public class AasUaEntityCollection : AasUaEntitySubmodelElementBase - { - public NodeState typeObjectOrdered = null; - - public AasUaEntityCollection(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // TODO (MIHO, 2020-08-06): use the collection element of UA? - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelElementCollectionType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:SubmodelElementCollection"); - this.typeObjectOrdered = this.entityBuilder.CreateAddObjectType("AASSubmodelElementOrderedCollectionType", - this.GetTypeNodeId(), preferredTypeNumId + 1, - descriptionKey: "AAS:SubmodelElementCollection"); - - // some elements - // ReSharper disable once RedundantExplicitArrayCreation - foreach (var o in new NodeState[] { this.typeObject /* , this.typeObjectOrdered */ }) - { - this.entityBuilder.CreateAddPropertyState(o, CreateMode.Type, "AllowDuplicates", - DataTypeIds.Boolean, false, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - } - - public NodeState CreateAddInstanceObject(NodeState parent, SubmodelElementCollection coll) - { - // access - if (coll == null) - return null; - - // containing element - var to = GetTypeObject().NodeId; - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, - "" + coll.IdShort, ReferenceTypeIds.HasComponent, to); - - // populate common attributes - base.PopulateInstanceObject(o, coll); - - // values - if (coll.Value != null) - foreach (var smw in coll.Value) - if (smw != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements( - o, CreateMode.Instance, smw); - - // result - return o; - } - } - - public class AasUaEntityFile : AasUaEntitySubmodelElementBase - { - public AasUaEntityFile(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASFileType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), - preferredTypeNumId, descriptionKey: "AAS:File"); - - // some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "MimeType", - this.entityBuilder.AasTypes.MimeType.GetTypeNodeId(), null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Value", - this.entityBuilder.AasTypes.PathType.GetTypeNodeId(), null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.FileType.CreateAddElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddInstanceObject(NodeState parent, File file) - { - // access - if (file == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, "" + file.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, file); - - // own attributes - this.entityBuilder.CreateAddPropertyState(o, CreateMode.Instance, "MimeType", - this.entityBuilder.AasTypes.MimeType.GetTypeNodeId(), file.ContentType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, CreateMode.Instance, "Value", - this.entityBuilder.AasTypes.PathType.GetTypeNodeId(), file.Value, defaultSettings: true); - - // wonderful working - // TODO (MIHO, 2021-01-01): re-enable with adoptions - /* - if (this.entityBuilder.AasTypes.FileType.CheckSuitablity(this.entityBuilder.package, file)) - this.entityBuilder.AasTypes.FileType.CreateAddElements( - o, CreateMode.Instance, this.entityBuilder.package, file); - */ - // result - return o; - } - } - - public class AasUaEntityBlob : AasUaEntitySubmodelElementBase - { - public AasUaEntityBlob(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASBlobType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:Blob"); - - // some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "ContentType", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, "Value", - DataTypeIds.String, null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, Blob blob) - { - // access - if (blob == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, "" + blob.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, blob); - - // own attributes - this.entityBuilder.CreateAddPropertyState(o, CreateMode.Instance, "ContentType", - DataTypeIds.String, blob.ContentType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, CreateMode.Instance, "Value", - DataTypeIds.String, blob.Value.ToString(), defaultSettings: true); - - // result - return o; - } - } - - public class AasUaEntityReferenceElement : AasUaEntitySubmodelElementBase - { - public AasUaEntityReferenceElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASReferenceElementType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:ReferenceElement"); - - // some elements - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "Value", - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, ReferenceElement refElem) - { - // access - if (refElem == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, "" + refElem.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, refElem); - - // own attributes - if (refElem is ReferenceElement referenceElement) - { - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, referenceElement.Value, "Value"); - } - - // result - return o; - } - } - - public class AasUaEntityRelationshipElement : AasUaEntitySubmodelElementBase - { - public AasUaEntityRelationshipElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASRelationshipElementType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:RelationshipElement"); - - // some elements - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "First", modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "Second", modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, RelationshipElement relElem) - { - // access - if (relElem == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, "" + relElem.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, relElem); - - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, relElem.First, "First"); - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, relElem.Second, "Second"); - - // result - return o; - } - } - - public class AasUaEntityOperationVariable : AasUaEntitySubmodelElementBase - { - public AasUaEntityOperationVariable(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("OperationVariableType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:OperationVariable"); - } - - public NodeState CreateAddInstanceObject(NodeState parent, OperationVariable opvar) - { - // access - if (opvar == null || opvar.Value == null || opvar.Value == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, - "" + opvar.Value.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, opvar.Value); - - // own attributes - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(o, CreateMode.Instance, opvar.Value); - - // result - return o; - } - } - - public class AasUaEntityOperation : AasUaEntitySubmodelElementBase - { - public AasUaEntityOperation(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASOperationType", - entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:Operation"); - - // indicate the Operation - this.entityBuilder.CreateAddMethodState(this.typeObject, CreateMode.Type, "Operation", - inputArgs: null, - outputArgs: null, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent); - - // some elements - for (int i = 0; i < 2; i++) - { - var o2 = this.entityBuilder.CreateAddObject(this.typeObject, CreateMode.Type, (i == 0) ? "in" : "out", - ReferenceTypeIds.HasComponent, - this.entityBuilder.AasTypes.OperationVariable.GetTypeObject().NodeId); - this.entityBuilder.AasTypes.OperationVariable.CreateAddInstanceObject(o2, null); - } - } - - public NodeState CreateAddInstanceObject(NodeState parent, Operation op) - { - // access - if (op == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, CreateMode.Instance, - "" + op.IdShort, - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, op); - - // own AAS attributes (in/out op vars) - //for (int i = 0; i < 2; i++) - //{ - // var opvarList = op[i]; - // if (opvarList != null && opvarList.Count > 0) - // { - // var o2 = this.entityBuilder.CreateAddObject(o, - // CreateMode.Instance, - // (i == 0) ? "OperationInputVariables" : "OperationOutputVariables", - // ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - // foreach (var opvar in opvarList) - // if (opvar != null && opvar.Value != null) - // this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements( - // o2, CreateMode.Instance, opvar.Value); - // } - //} - - var opInputVarList = op.InputVariables; - if (opInputVarList != null && opInputVarList.Count > 0) - { - var o2 = this.entityBuilder.CreateAddObject(o, - CreateMode.Instance, - "OperationInputVariables", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - foreach (var opvar in opInputVarList) - if (opvar != null && opvar.Value != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements( - o2, CreateMode.Instance, opvar.Value); - } - - var opOutputVarList = op.OutputVariables; - if (opOutputVarList != null && opOutputVarList.Count > 0) - { - var o2 = this.entityBuilder.CreateAddObject(o, - CreateMode.Instance, - "OperationOutputVariables", - ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - foreach (var opvar in opOutputVarList) - if (opvar != null && opvar.Value != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements( - o2, CreateMode.Instance, opvar.Value); - } - - // create a method? - if (true) - { - // ReSharper disable once RedundantExplicitArrayCreation - var args = new List[] { new List(), new List() }; - for (int i = 0; i < 2; i++) - { - if (i == 0) - { - CreateOperationArguments(i, ref args, op.InputVariables); - } - else if (i == 1) - { - CreateOperationArguments(i, ref args, op.OutputVariables); - } - } - - var unused = this.entityBuilder.CreateAddMethodState(o, CreateMode.Instance, "Operation", - inputArgs: args[0].ToArray(), - outputArgs: args[1].ToArray(), - referenceTypeFromParentId: ReferenceTypeIds.HasComponent); - } - - // result - return o; - } - - private void CreateOperationArguments(int i, ref List[] args, List opVariables) - { - if (opVariables != null) - { - foreach (var opvar in opVariables) - { - // TODO (MIHO, 2020-08-06): decide to from where the name comes - var name = "noname"; - - // TODO (MIHO, 2020-08-06): description: get "en" Version which is appropriate? - LocalizedText desc = new LocalizedText(""); - - // TODO (MIHO, 2020-08-06): parse UA data type out .. OK? - NodeId dataType = null; - if (opvar.Value != null && opvar.Value != null) - { - // better name .. but not best (see below) - if (opvar.Value.IdShort != null - && opvar.Value.IdShort.Trim() != "") - name = "" + opvar.Value.IdShort; - - // TODO (MIHO, 2020-08-06): description: get "en" Version is appropriate? - desc = AasUaUtils.GetBestUaDescriptionFromAasDescription( - opvar.Value.Description); - - // currenty, only accept properties as in/out arguments. - // Only these have an XSD value type!! - var prop = opvar.Value as Property; - if (prop != null && prop.ValueType != null) - { - // TODO (MIHO, 2020-08-06): this any better? - if (prop.IdShort != null && prop.IdShort.Trim() != "") - name = "" + prop.IdShort; - - // TODO (MIHO, 2020-08-06): description: get "en" Version is appropriate? - if (desc.Text == null || desc.Text == "") - desc = AasUaUtils.GetBestUaDescriptionFromAasDescription( - opvar.Value.Description); - - // try convert type - if (!AasUaUtils.AasValueTypeToUaDataType( - prop.ValueType.ToString(), out var dummy, out dataType)) - dataType = null; - } - } - if (dataType == null) - continue; - - var a = new Argument(name, dataType, -1, desc.Text ?? ""); - args[i].Add(a); - } - - } - } - } - - - public class AasUaEntityDataSpecification : AasUaBaseEntity - { - public AasUaEntityDataSpecification(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASDataSpecificationType", - ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:DataSpecification"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - } - - } - - public class AasUaEntityDataSpecificationIEC61360 : AasUaBaseEntity - { - public AasUaEntityDataSpecificationIEC61360(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASDataSpecificationIEC61360Type", - this.entityBuilder.AasTypes.DataSpecification.GetTypeNodeId(), preferredTypeNumId, - descriptionKey: "AAS:DataSpecificationIEC61360"); - - // very special rule here for the Identifiable - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Instance, - //new IIdentifiable("http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360"), - "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360", - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Instance, - new AdministrativeInformation(version: "1", revision: "0"), - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - // add some more elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "PreferredName", - DataTypeIds.LocalizedText, - value: null, defaultSettings: true, valueRank: 1, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "ShortName", - DataTypeIds.String, value: null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "Unit", - DataTypeIds.String, value: null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, - "UnitId", - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "SourceOfDefinition", - DataTypeIds.LocalizedText, - value: null, defaultSettings: true, valueRank: 1, - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "Symbol", DataTypeIds.String, - value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "DataType", DataTypeIds.String, - value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "Definition", - DataTypeIds.LocalizedText, value: null, defaultSettings: true, valueRank: 1, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, CreateMode.Type, - "ValueFormat", - DataTypeIds.String, value: null, defaultSettings: true, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - // TODO (jtikekar, 2023-09-04): jtikekar Temporarily commented - //public NodeState CreateAddElements(NodeState parent, CreateMode mode, - // AdminShell.DataSpecificationIEC61360 ds = null, - // AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - //{ - // if (parent == null) - // return null; - - // // for the sake of clarity, we're directly splitting cases - // if (mode == CreateMode.Type) - // { - // // containing element (only) - // var o = this.entityBuilder.CreateAddObject(parent, mode, "DataSpecificationIEC61360", - // this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), GetTypeObject().NodeId, - // modellingRule: modellingRule); - // return o; - // } - // else - // { - // // access - // if (ds == null) - // return null; - - // // we can only provide minimal unique naming - // var name = "DataSpecificationIEC61360"; - // if (ds.shortName != null && this.entityBuilder.RootDataSpecifications != null) - // name += "_" + ds.shortName; - - // // containing element (depending on root folder) - // NodeState o = null; - // if (this.entityBuilder.RootDataSpecifications != null) - // { - // // under common folder - // o = this.entityBuilder.CreateAddObject(this.entityBuilder.RootDataSpecifications, mode, name, - // ReferenceTypeIds.Organizes, GetTypeObject().NodeId); - // // link to this object - // parent.AddReference(this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), false, o.NodeId); - // } - // else - // { - // // under parent - // o = this.entityBuilder.CreateAddObject(parent, mode, name, - // this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), GetTypeObject().NodeId); - // } - - // // add some elements - // if (ds.preferredName != null && ds.preferredName.Count > 0) - // this.entityBuilder.CreateAddPropertyState(o, mode, "PreferredName", - // DataTypeIds.LocalizedText, - // value: AasUaUtils.GetUaLocalizedTexts(ds.preferredName), - // defaultSettings: true, valueRank: 1); - - // if (ds.shortName != null && ds.shortName.Count > 0) - // this.entityBuilder.CreateAddPropertyState(o, mode, "ShortName", - // DataTypeIds.LocalizedText, - // value: AasUaUtils.GetUaLocalizedTexts(ds.shortName), - // defaultSettings: true, valueRank: 1); - - // if (ds.unit != null) - // this.entityBuilder.CreateAddPropertyState(o, mode, "Unit", - // DataTypeIds.String, value: ds.unit, defaultSettings: true); - - // if (ds.unitId != null) - // this.entityBuilder.AasTypes.Reference.CreateAddElements(o, mode, - // Reference.CreateNew(ds.unitId?.Value), "UnitId"); - - // if (ds.sourceOfDefinition != null) - // this.entityBuilder.CreateAddPropertyState(o, mode, "SourceOfDefinition", - // DataTypeIds.String, value: ds.sourceOfDefinition, defaultSettings: true); - - // if (ds.symbol != null) - // this.entityBuilder.CreateAddPropertyState(o, mode, "Symbol", - // DataTypeIds.String, value: ds.symbol, defaultSettings: true); - - // if (ds.dataType != null) - // this.entityBuilder.CreateAddPropertyState(o, mode, "DataType", - // DataTypeIds.String, value: ds.dataType, defaultSettings: true); - - // if (ds.definition != null && ds.definition.Count > 0) - // this.entityBuilder.CreateAddPropertyState(o, mode, "Definition", - // DataTypeIds.LocalizedText, value: AasUaUtils.GetUaLocalizedTexts(ds.definition), - // defaultSettings: true, valueRank: 1); - - // if (ds.ValueFormat != null) - // this.entityBuilder.CreateAddPropertyState(o, mode, "ValueFormat", - // DataTypeIds.String, value: ds.ValueFormat, defaultSettings: true); - - // // return - // return o; - // } - //} - } - - public class AasUaEntityConceptDescription : AasUaBaseEntity - { - public NodeState typeObjectIrdi; - public NodeState typeObjectUri; - public NodeState typeObjectCustom; - - - public AasUaEntityConceptDescription(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // TODO (MIHO, 2020-08-06): check, if to make super classes for UriDictionaryEntryType? - this.typeObjectIrdi = this.entityBuilder.CreateAddObjectType("AASIrdiConceptDescriptionType", - this.entityBuilder.AasTypes.IrdiDictionaryEntryType.GetTypeNodeId(), 0, - descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectIrdi, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - this.typeObjectUri = this.entityBuilder.CreateAddObjectType("AASUriConceptDescriptionType", - this.entityBuilder.AasTypes.UriDictionaryEntryType.GetTypeNodeId(), 0, - descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectUri, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - this.typeObjectCustom = this.entityBuilder.CreateAddObjectType("AASCustomConceptDescriptionType", - this.entityBuilder.AasTypes.DictionaryEntryType.GetTypeNodeId(), 0, - descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectCustom, false, - this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // for each of them, add some elements - // ReSharper disable once RedundantExplicitArrayCreation - foreach (var o in new NodeState[] { this.typeObjectIrdi, this.typeObjectUri, this.typeObjectCustom }) - { - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // IsCaseOf - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Type, null, "IsCaseOf", - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Type, null, "DataSpecification", - modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - // data specification is a child - // TODO (jtikekar, 2023-09-04): Temporarily commented - //this.entityBuilder.AasTypes.DataSpecificationIEC61360.CreateAddElements(o, CreateMode.Type, - // modellingRule: AasUaNodeHelper.ModellingRule.MandatoryPlaceholder); - } - } - - public NodeState GetTypeObjectFor(string identification) - { - var to = this.typeObject; // shall be NULL - - //commented as per new V3.0RC02 - //if (true == identification?.IsIRI()) - // to = this.typeObjectUri; - //else - //if (true == identification?.IsIRDI()) - // to = this.typeObjectIrdi; - - // TODO (MIHO, 2021-12-30): before V3.0, there was a compare to "custom" here. - - return to; - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, IConceptDescription cd = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - // split directly because of complexity - if (mode == CreateMode.Type) - { - // not sure, if this will required, ever - return null; - } - else - { - // access - if (cd == null) - return null; - - // makeup name - var name = "ConceptDescription_" + Guid.NewGuid().ToString(); - - if (false) -#pragma warning disable 162 - // ReSharper disable HeuristicUnreachableCode - { - // Conventional approach: build up a speaking name - // but: shall be target of "HasDictionaryEntry", therefore the __PURE__ identifications - // need to be the name! - // TODO (jtikekar, 2023-09-04): Temporarily commented - //if (cd.GetIEC61360() != null) - //{ - // var ds = cd.GetIEC61360(); - // if (ds.shortName != null) - // name = ds.shortName.GetDefaultStr(); - // if (cd.Id != null) - // name += "_" + cd.Id.ToString(); - //} - name = AasUaUtils.ToOpcUaName(name); - } - // ReSharper enable HeuristicUnreachableCode -#pragma warning restore 162 - else - { - // only identification (the type object will distinct between the id type) - if (cd.Id != null) - name = cd.Id; - } - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, mode, name, - ReferenceTypeIds.HasComponent, this.GetTypeObjectFor(cd.Id)?.NodeId, - modellingRule: modellingRule); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements( - o, CreateMode.Instance, cd); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements( - o, CreateMode.Instance, cd.Id); - this.entityBuilder.AasTypes.Administration.CreateAddElements( - o, CreateMode.Instance, cd.Administration); - // IsCaseOf - if (cd.IsCaseOf != null) - foreach (var ico in cd.IsCaseOf) - this.entityBuilder.AasTypes.Reference.CreateAddElements( - o, CreateMode.Instance, ico, "IsCaseOf"); - - // HasDataSpecification solely under the viewpoint of IEC61360 - // TODO (jtikekar, 2023-09-04): Temporarily commented - //var eds = cd.embeddedDataSpecification?.IEC61360; - //if (eds != null) - // this.entityBuilder.AasTypes.Reference.CreateAddElements( - // o, CreateMode.Instance, eds.dataSpecification, "DataSpecification"); - - // data specification is a child - /// TODO (jtikekar, 2023-09-04): Temporarily commented - //var ds61360 = cd.embeddedDataSpecification?.IEC61360Content; - //if (ds61360 != null) - //{ - // var unused = this.entityBuilder.AasTypes.DataSpecificationIEC61360.CreateAddElements( - // o, CreateMode.Instance, - // ds61360); - //} - - // remember CD as NodeRecord - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, cd.Id)); - - return o; - } - } - } - - // - // Elements from the UA spc - // - - public class AasUaNamespaceZeroEntity : AasUaBaseEntity - { - public AasUaNamespaceZeroEntity(AasEntityBuilder entityBuilder, uint presetNumId = 0) - : base(entityBuilder) - { - // just set node id based on existing knowledge - this.typeObjectId = new NodeId(presetNumId, 0); - } - } - - public class AasUaNamespaceZeroReference : AasUaBaseEntity - { - public AasUaNamespaceZeroReference(AasEntityBuilder entityBuilder, uint presetNumId = 0) - : base(entityBuilder) - { - // just set node id based on existing knowledge - this.typeObjectId = new NodeId(presetNumId, 0); - } - - public void CreateAddInstanceReference(NodeState source, bool isInverse, ExpandedNodeId target) - { - if (source != null && target != null && this.GetTypeNodeId() != null) - source.AddReference(this.GetTypeNodeId(), isInverse, target); - } - } - - // - // References - // - - public class AasUaReferenceHasAasReference : AasUaBaseEntity - { - public AasUaReferenceHasAasReference(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddReferenceType("AASReference", "AASReferencedBy", - preferredTypeNumId, useZeroNS: false); - } - - public NodeState CreateAddInstanceReference(NodeState parent) - { - return null; - } - } - - - // - // Interfaces - // - - public class AasUaInterfaceAASIdentifiableType : AasUaBaseEntity - { - public AasUaInterfaceAASIdentifiableType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("IAASIdentifiableType", - this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId() /* ObjectTypeIds.BaseObjectType */, - preferredTypeNumId, descriptionKey: "AAS:Identifiable"); - - // add some elements - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - } - - public class AasUaInterfaceAASReferableType : AasUaBaseEntity - { - public AasUaInterfaceAASReferableType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("IAASReferableType", - this.entityBuilder.AasTypes.BaseInterfaceType.GetTypeNodeId() /* ObjectTypeIds.BaseObjectType */, - preferredTypeNumId, descriptionKey: "AAS:Referable"); - - // some elements - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - } - } -} diff --git a/src/AasxServerStandardBib/AasUaEntities.cs.bak b/src/AasxServerStandardBib/AasUaEntities.cs.bak deleted file mode 100644 index 20aadaafb..000000000 --- a/src/AasxServerStandardBib/AasUaEntities.cs.bak +++ /dev/null @@ -1,1668 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using AdminShellNS; -using Opc.Ua; - -namespace AasOpcUaServer -{ - public class AasUaBaseEntity - { - public enum CreateMode { Type, Instance }; - - /// - /// Reference back to the entity builder - /// - protected AasEntityBuilder entityBuilder = null; - - public AasUaBaseEntity(AasEntityBuilder entityBuilder) - { - this.entityBuilder = entityBuilder; - } - - /// - /// Typically the node of the entity in the AAS type object space - /// - protected NodeState typeObject = null; - - /// - /// If the entitiy does not have a direct type object, the object id instead (for pre-defined objects) - /// - protected NodeId typeObjectId = null; - - /// - /// Getter of the type object - /// - public NodeState GetTypeObject() - { - return typeObject; - } - - /// - /// Getter of the type object id, either directly or via the type object (if avilable) - /// - /// - public NodeId GetTypeNodeId() - { - if (typeObjectId != null) - return typeObjectId; - if (typeObject == null) - return null; - return typeObject.NodeId; - } - } - - public class AasUaEntityPathType : AasUaBaseEntity - { - public AasUaEntityPathType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type elements - this.typeObject = this.entityBuilder.CreateAddDataType("AASPathType", DataTypeIds.String); - } - } - - public class AasUaEntityMimeType : AasUaBaseEntity - { - public AasUaEntityMimeType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type elements - this.typeObject = this.entityBuilder.CreateAddDataType("AASMimeType", DataTypeIds.String); - } - } - - public class AasUaEntityIdentification : AasUaBaseEntity - { - public AasUaEntityIdentification(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASIdentifierType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Identifier"); - // add some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, "IdType", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Id", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.Identification identification = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, "Identification", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - this.entityBuilder.CreateAddPropertyState(o, "IdType", DataTypeIds.String, "" + "" + identification.idType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, "Id", DataTypeIds.String, "" + "" + identification.id, defaultSettings: true); - } - - return o; - } - } - - public class AasUaEntityAdministration : AasUaBaseEntity - { - public AasUaEntityAdministration(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAdministrativeInformationType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:AdministrativeInformation"); - // add some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Version", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Revision", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.Administration administration = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && administration == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, "Administration", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - if (administration == null) - return null; - this.entityBuilder.CreateAddPropertyState(o, "Version", DataTypeIds.String, "" + "" + administration.version, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, "Revision", DataTypeIds.String, "" + "" + administration.revision, defaultSettings: true); - } - - return o; - } - } - - public class AasUaEntityQualifier : AasUaBaseEntity - { - public AasUaEntityQualifier(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASQualifierType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, "AAS:Qualifier"); - - // add some elements - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Type", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Value", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "ValueId", AasUaNodeHelper.ModellingRule.Optional); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, Qualifier qualifier = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && qualifier == null) - return null; - - if (mode == CreateMode.Type) - { - // plain - var o = this.entityBuilder.CreateAddObject(parent, "Qualifier", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - // need data - if (qualifier == null) - return null; - - // do a little extra? - string extraName = null; - if (qualifier.type != null && qualifier.type.Length > 0) - { - extraName = "Qualifier:" + qualifier.type; - if (qualifier.Value != null && qualifier.Value.Length > 0) - extraName += "=" + qualifier.Value; - } - - var o = this.entityBuilder.CreateAddObject(parent, "Qualifier", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule, extraName: extraName); - - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(o, CreateMode.Instance, qualifier.semanticId, "SemanticId"); - this.entityBuilder.CreateAddPropertyState(o, "Type", DataTypeIds.String, "" + qualifier.type, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.String, "" + qualifier.Value, defaultSettings: true); - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, qualifier.ValueId, "ValueId"); - - return o; - } - - } - } - - public class AasUaEntityAssetKind : AasUaBaseEntity - { - public AasUaEntityAssetKind(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // no special type here (is a string) - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.AssetKind kind = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (mode == CreateMode.Instance && kind == null) - return null; - - var o = this.entityBuilder.CreateAddPropertyState(parent, "Kind", DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + kind.kind, defaultSettings: true, modellingRule: modellingRule); - - return o; - } - } - - public class AasUaEntityModelingKind : AasUaBaseEntity - { - public AasUaEntityModelingKind(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // no special type here (is a string) - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.ModelingKind kind = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (mode == CreateMode.Instance && kind == null) - return null; - - var o = this.entityBuilder.CreateAddPropertyState(parent, "Kind", DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + kind.kind, defaultSettings: true, modellingRule: modellingRule); - - return o; - } - } - - public class AasUaEntityReferable : AasUaBaseEntity - { - public AasUaEntityReferable(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // NO type object required - // see IAASReferable interface - } - - /// - /// This adds all Referable attributes to the parent and re-defines the descriptons - /// - public NodeState CreateAddElements(NodeState parent, CreateMode mode, IReferable refdata = null) - { - if (parent == null) - return null; - if (mode == CreateMode.Instance && refdata == null) - return null; - - if (mode == CreateMode.Type || refdata?.category != null) - this.entityBuilder.CreateAddPropertyState(parent, "Category", DataTypeIds.String, (mode == CreateMode.Type) ? null : "" + refdata.category, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - - - if (mode == CreateMode.Instance) - { - // now, re-set the description on the parent - // ISSUE: only ONE language supported! - parent.Description = AasUaUtils.GetBestUaDescriptionFromAasDescription(refdata.description); - } - - return null; - } - } - - public class AasUaEntityReferenceBase : AasUaBaseEntity - { - public AasUaEntityReferenceBase(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // nothing, only used to share code - } - - /// - /// Sets the "Keys" value information of an AAS Reference. This is especially important for referencing outwards of the AAS (environment). - /// - public void CreateAddKeyElements(NodeState parent, CreateMode mode, List keys = null) - { - if (parent == null) - return; - - // MIHO: open62541 does not to process Values as string[], therefore change it temporarily - - if (this.entityBuilder != null && this.entityBuilder.theServerOptions != null && this.entityBuilder.theServerOptions.ReferenceKeysAsSingleString) - { - // fix for open62541 - var keyo = this.entityBuilder.CreateAddPropertyState(parent, "Keys", DataTypeIds.String, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - keyo.Value = AasUaUtils.ToOpcUaReference(AdminShell.Reference.CreateNew(keys)); - } - } - else - { - // default behaviour - var keyo = this.entityBuilder.CreateAddPropertyState(parent, "Keys", DataTypeIds.Structure, null, defaultSettings: true); - - if (mode == CreateMode.Instance && keyo != null) - { - keyo.Value = AasUaUtils.ToOpcUaReferenceList(AdminShell.Reference.CreateNew(keys))?.ToArray(); - } - } - } - - /// - /// Sets the UA relation of an AAS Reference. This is especially important for reference within an AAS node structure, to be - /// in the style of OPC UA - /// - public void CreateAddReferenceElements(NodeState parent, CreateMode mode, List keys = null) - { - if (parent == null) - return; - - if (mode == CreateMode.Type) - { - // makes no sense - } - else - { - // would make sense, but is replaced by the code in "CreateAddInstanceObjects" directly. - } - } - } - - public class AasUaEntityReference : AasUaEntityReferenceBase - { - public AasUaEntityReference(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASReferenceType", ObjectTypeIds.BaseObjectType, preferredTypeNumId); - // with some elements - this.CreateAddKeyElements(this.typeObject, CreateMode.Type); - this.CreateAddReferenceElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.Reference reference, string browseDisplayName = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - var o = this.entityBuilder.CreateAddObject(parent, browseDisplayName ?? "Reference", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - if (reference == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, browseDisplayName ?? "Reference", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // explicit strings? - this.CreateAddKeyElements(o, mode, reference.Keys); - - // find a matching concept description or other referable? - // as we do not have all other nodes realized, store a late action - this.entityBuilder.AddNodeLateAction( - new AasEntityBuilder.NodeLateActionLinkToReference( - o, - reference, - AasEntityBuilder.NodeLateActionLinkToReference.ActionType.SetAasReference - )); - - // OK - return o; - } - } - } - - public class AasUaEntitySemanticId : AasUaEntityReferenceBase - { - public AasUaEntitySemanticId(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // re-use AASReferenceType for this - this.typeObject = this.entityBuilder.AasTypes.Reference.GetTypeObject(); - // with some elements - this.CreateAddReferenceElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddInstanceObject(NodeState parent, CreateMode mode, AdminShell.SemanticId semid = null, string browseDisplayName = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - var o = this.entityBuilder.CreateAddObject(parent, browseDisplayName ?? "SemanticId", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - if (semid == null) - return null; - - var o = this.entityBuilder.CreateAddObject(parent, browseDisplayName ?? "SemanticId", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // explicit strings? - this.CreateAddKeyElements(o, mode, semid.Keys); - - // find a matching concept description or other referable? - // as we do not have all other nodes realized, store a late action - this.entityBuilder.AddNodeLateAction( - new AasEntityBuilder.NodeLateActionLinkToReference( - parent, - new AdminShell.Reference(semid), - AasEntityBuilder.NodeLateActionLinkToReference.ActionType.SetDictionaryEntry - )); - - // OK - return o; - } - } - } - - public class AasUaEntityAsset : AasUaBaseEntity - { - public AasUaEntityAsset(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAssetType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Asset"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add necessary type information - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.AssetKind.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "AssetIdentificationModel", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.Asset asset = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && asset == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "Asset", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - // access - if (asset == null) - return null; - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, asset)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, asset); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Instance, asset.identification); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Instance, asset.administration); - // HasKind - this.entityBuilder.AasTypes.AssetKind.CreateAddElements(o, CreateMode.Instance, asset.kind); - // HasDataSpecification - if (asset.hasDataSpecification != null && asset.hasDataSpecification.reference != null) - foreach (var ds in asset.hasDataSpecification.reference) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ds, "DataSpecification"); - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, asset.assetIdentificationModelRef, "AssetIdentificationModel"); - } - - return o; - } - } - - public class AasUaEntityAAS : AasUaBaseEntity - { - public AasUaEntityAAS(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASAssetAdministrationShellType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:AssetAdministrationShell"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add necessary type information - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DerivedFrom", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // assets - this.entityBuilder.AasTypes.Asset.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // associated views - this.entityBuilder.AasTypes.View.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // associated submodels - this.entityBuilder.AasTypes.Submodel.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // concept dictionary - this.entityBuilder.AasTypes.ConceptDictionary.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddInstanceObject(NodeState parent, AasCore.Aas3_0_RC02.Environment env, AssetAdministrationShell aas) - { - // access - if (env == null || aas == null) - return null; - - // containing element - string extraName = null; - string browseName = "AssetAdministrationShell"; - if (aas.IdShort != null && aas.IdShort.Trim().Length > 0) - { - extraName = "AssetAdministrationShell:" + aas.IdShort; - browseName = aas.IdShort; - } - var o = this.entityBuilder.CreateAddObject(parent, browseName, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, - extraName: extraName); - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, aas)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, aas); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Instance, aas.identification); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Instance, aas.administration); - // HasDataSpecification - if (aas.hasDataSpecification != null && aas.hasDataSpecification.reference != null) - foreach (var ds in aas.hasDataSpecification.reference) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ds, "DataSpecification"); - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, aas.derivedFrom, "DerivedFrom"); - - // associated asset - if (aas.assetRef != null) - { - var asset = env.FindAsset(aas.assetRef); - if (asset != null) - this.entityBuilder.AasTypes.Asset.CreateAddElements(o, CreateMode.Instance, asset); - } - - // associated views - if (aas.views != null) - foreach (var vw in aas.views.views) - this.entityBuilder.AasTypes.View.CreateAddElements(o, CreateMode.Instance, vw); - - // associated submodels - if (aas.Submodels != null && aas.Submodels.Count > 0) - foreach (var smr in aas.Submodels) - { - var sm = env.FindSubmodel(smr); - if (sm != null) - this.entityBuilder.AasTypes.Submodel.CreateAddElements(o, CreateMode.Instance, sm); - } - - // make up CD dictionaries - if (aas.conceptDictionaries != null && aas.conceptDictionaries.Count > 0) - { - foreach (var cdd in aas.conceptDictionaries) - { - // TODO: reference to CDs. They are stored sepaately - } - } - - // results - return o; - } - } - - public class AasUaEntitySubmodel : AasUaBaseEntity - { - public AasUaEntitySubmodel(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:Submodel"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // add some elements - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // Qualifiable - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // SubmodelElements - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, Submodel sm = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - // create only containing element with generic name - var o = this.entityBuilder.CreateAddObject(parent, "Submodel", ReferenceTypeIds.HasComponent, this.GetTypeNodeId(), modellingRule: modellingRule); - return o; - } - else - { - // access - if (sm == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + sm.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, extraName: "Submodel:" + sm.IdShort); - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, sm)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, sm); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Instance, sm.identification); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Instance, sm.administration); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(o, CreateMode.Instance, sm.semanticId, "SemanticId"); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(o, CreateMode.Instance, sm.kind); - // HasDataSpecification - if (sm.hasDataSpecification != null && sm.hasDataSpecification.reference != null) - foreach (var ds in sm.hasDataSpecification.reference) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ds, "DataSpecification"); - // Qualifiable - if (sm.qualifiers != null) - foreach (var q in sm.qualifiers) - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(o, CreateMode.Instance, q); - - // SubmodelElements - if (sm.submodelElements != null) - foreach (var smw in sm.submodelElements) - if (smw.submodelElement != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(o, CreateMode.Instance, smw); - - // result - return o; - } - } - } - - /// - /// This class is for the representation if SME in UA namespace - /// - public class AasUaEntitySubmodelElement : AasUaBaseEntity - { - public AasUaEntitySubmodelElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelElementType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:SubmodelElement"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId()); - - // add some elements to the type - // Note: in this special case, the instance elements are populated by AasUaEntitySubmodelElementBase, while the elements - // for the type are populated here - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(this.typeObject, CreateMode.Type, null, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // Qualifiable - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - } - - /// - /// This class is the base class of derived properties - /// - public class AasUaEntitySubmodelElementBase : AasUaBaseEntity - { - public AasUaEntitySubmodelElementBase(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // do NOT create type object, as this is done by sub-class - } - - public NodeState PopulateInstanceObject(NodeState o, SubmodelElement sme) - { - // access - if (o == null || sme == null) - return null; - - // take this as perfect opportunity to register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, sme)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, sme); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(o, CreateMode.Instance, sme.semanticId, "SemanticId"); - // HasKind - this.entityBuilder.AasTypes.ModelingKind.CreateAddElements(o, CreateMode.Instance, sme.kind); - // HasDataSpecification - if (sme.hasDataSpecification != null && sme.hasDataSpecification.reference != null) - foreach (var ds in sme.hasDataSpecification.reference) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ds, "DataSpecification"); - // Qualifiable - if (sme.qualifiers != null) - foreach (var q in sme.qualifiers) - this.entityBuilder.AasTypes.Qualifier.CreateAddElements(o, CreateMode.Instance, q); - - // result - return o; - } - } - - /// - /// This class will automatically instantiate the correct SubmodelElement entity. - /// - public class AasUaEntitySubmodelWrapper : AasUaBaseEntity - { - public AasUaEntitySubmodelWrapper(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // do NOT create type object, as this is done by sub-class - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, SubmodelElementWrapper smw = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - // access - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - - - // create only containing element (base type) with generic name - var o = this.entityBuilder.CreateAddObject(parent, "SubmodelElement", ReferenceTypeIds.HasComponent, this.entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), modellingRule: modellingRule); - return o; - } - else - { - if (smw == null || smw.submodelElement == null) - return null; - - if (smw.submodelElement is SubmodelElementCollection) - { - var coll = smw.submodelElement as SubmodelElementCollection; - return this.entityBuilder.AasTypes.Collection.CreateAddInstanceObject(parent, coll); - } - else if (smw.submodelElement is Property) - return this.entityBuilder.AasTypes.Property.CreateAddInstanceObject(parent, smw.submodelElement as Property); - else if (smw.submodelElement is File) - return this.entityBuilder.AasTypes.File.CreateAddInstanceObject(parent, smw.submodelElement as File); - else if (smw.submodelElement is Blob) - return this.entityBuilder.AasTypes.Blob.CreateAddInstanceObject(parent, smw.submodelElement as Blob); - else if (smw.submodelElement is ReferenceElement) - return this.entityBuilder.AasTypes.ReferenceElement.CreateAddInstanceObject(parent, smw.submodelElement as ReferenceElement); - else if (smw.submodelElement is RelationshipElement) - return this.entityBuilder.AasTypes.RelationshipElement.CreateAddInstanceObject(parent, smw.submodelElement as RelationshipElement); - else if (smw.submodelElement is Operation) - return this.entityBuilder.AasTypes.Operation.CreateAddInstanceObject(parent, smw.submodelElement as Operation); - - // nope - return null; - } - } - } - - public class AasUaEntityProperty : AasUaEntitySubmodelElementBase - { - public AasUaEntityProperty(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASPropertyType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:Property"); - - // elements not in the base type - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Instance, null, "ValueId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "ValueType", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Value", DataTypeIds.BaseDataType, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, Property prop) - { - // access - if (prop == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + prop.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, prop); - - // TODO: not sure if to add these - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, prop.ValueId, "ValueId"); - this.entityBuilder.CreateAddPropertyState(o, "ValueType", DataTypeIds.String, "" + prop.ValueType, defaultSettings: true); - - // TODO: aim is to support many types natively - var vt = (prop.ValueType ?? "").ToLower().Trim(); - if (vt == "boolean") - { - var x = (prop.Value ?? "").ToLower().Trim(); - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Boolean, x == "true", defaultSettings: true); - } - else if (vt == "datetime" || vt == "datetimestamp" || vt == "time") - { - DateTime dt; - if (DateTime.TryParse(prop.Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.DateTime, dt.ToFileTimeUtc(), defaultSettings: true); - } - else if (vt == "decimal" || vt == "integer" || vt == "long" || vt == "nonpositiveinteger" || vt == "negativeinteger") - { - Int64 v; - if (Int64.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Int64, v, defaultSettings: true); - } - else if (vt == "int") - { - Int32 v; - if (Int32.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Int32, v, defaultSettings: true); - } - else if (vt == "short") - { - Int16 v; - if (Int16.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Int16, v, defaultSettings: true); - } - else if (vt == "byte") - { - SByte v; - if (SByte.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Byte, v, defaultSettings: true); - } - else if (vt == "nonnegativeinteger" || vt == "positiveinteger" || vt == "unsignedlong") - { - UInt64 v; - if (UInt64.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.UInt64, v, defaultSettings: true); - } - else if (vt == "unsignedint") - { - UInt32 v; - if (UInt32.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.UInt32, v, defaultSettings: true); - } - else if (vt == "unsignedshort") - { - UInt16 v; - if (UInt16.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.UInt16, v, defaultSettings: true); - } - else if (vt == "unsignedbyte") - { - Byte v; - if (Byte.TryParse(prop.Value, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Byte, v, defaultSettings: true); - } - else if (vt == "double") - { - double v; - if (double.TryParse(prop.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Double, v, defaultSettings: true); - } - else if (vt == "float") - { - float v; - if (float.TryParse(prop.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out v)) - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.Float, v, defaultSettings: true); - } - else - { - // leave in string - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.String, prop.Value, defaultSettings: true); - } - - // result - return o; - } - } - - public class AasUaEntityCollection : AasUaEntitySubmodelElementBase - { - public NodeState typeObjectOrdered = null; - - public AasUaEntityCollection(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // TODO: use the collection element of UA - this.typeObject = this.entityBuilder.CreateAddObjectType("AASSubmodelElementCollectionType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:SubmodelElementCollection"); - this.typeObjectOrdered = this.entityBuilder.CreateAddObjectType("AASSubmodelElementOrderedCollectionType", this.GetTypeNodeId(), preferredTypeNumId + 1, descriptionKey: "AAS:SubmodelElementCollection"); - - // some elements - foreach (var o in new NodeState[] { this.typeObject /* , this.typeObjectOrdered */ }) - { - this.entityBuilder.CreateAddPropertyState(o, "AllowDuplicates", DataTypeIds.Boolean, false, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - } - - public NodeState CreateAddInstanceObject(NodeState parent, SubmodelElementCollection coll) - { - // access - if (coll == null) - return null; - - // containing element - var to = GetTypeObject().NodeId; - if (coll.ordered && this.typeObjectOrdered != null) - to = this.typeObjectOrdered.NodeId; - var o = this.entityBuilder.CreateAddObject(parent, "" + coll.IdShort, ReferenceTypeIds.HasComponent, to); - - // populate common attributes - base.PopulateInstanceObject(o, coll); - - // own attributes - this.entityBuilder.CreateAddPropertyState(o, "AllowDuplicates", DataTypeIds.Boolean, coll.allowDuplicates, defaultSettings: true); - - // values - if (coll.Value != null) - foreach (var smw in coll.Value) - if (smw.submodelElement != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(o, CreateMode.Instance, smw); - - // result - return o; - } - } - - public class AasUaEntityFile : AasUaEntitySubmodelElementBase - { - public AasUaEntityFile(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASFileType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:File"); - - // some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, "MimeType", this.entityBuilder.AasTypes.MimeType.GetTypeNodeId(), null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Value", this.entityBuilder.AasTypes.PathType.GetTypeNodeId(), null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.FileType.CreateAddElements(this.typeObject, CreateMode.Type); - } - - public NodeState CreateAddInstanceObject(NodeState parent, File file) - { - // access - if (file == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + file.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, file); - - // own attributes - this.entityBuilder.CreateAddPropertyState(o, "MimeType", this.entityBuilder.AasTypes.MimeType.GetTypeNodeId(), file.mimeType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, "Value", this.entityBuilder.AasTypes.PathType.GetTypeNodeId(), file.Value, defaultSettings: true); - - // wonderful working - if (this.entityBuilder.AasTypes.FileType.CheckSuitablity(this.entityBuilder.package, file)) - this.entityBuilder.AasTypes.FileType.CreateAddElements(o, CreateMode.Instance, this.entityBuilder.package, file); - - // result - return o; - } - } - - public class AasUaEntityBlob : AasUaEntitySubmodelElementBase - { - public AasUaEntityBlob(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASBlobType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:Blob"); - - // some elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, "MimeType", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Value", DataTypeIds.String, null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, Blob blob) - { - // access - if (blob == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + blob.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, blob); - - // own attributes - this.entityBuilder.CreateAddPropertyState(o, "MimeType", DataTypeIds.String, blob.mimeType, defaultSettings: true); - this.entityBuilder.CreateAddPropertyState(o, "Value", DataTypeIds.String, blob.Value, defaultSettings: true); - - // result - return o; - } - } - - public class AasUaEntityReferenceElement : AasUaEntitySubmodelElementBase - { - public AasUaEntityReferenceElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASReferenceElementType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:ReferenceElement"); - - // some elements - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "Value", modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, ReferenceElement refElem) - { - // access - if (refElem == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + refElem.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, refElem); - - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, refElem.Value, "Value"); - - // result - return o; - } - } - - public class AasUaEntityRelationshipElement : AasUaEntitySubmodelElementBase - { - public AasUaEntityRelationshipElement(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASRelationshipElementType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:RelationshipElement"); - - // some elements - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "First", modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "Second", modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddInstanceObject(NodeState parent, RelationshipElement relElem) - { - // access - if (relElem == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + relElem.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, relElem); - - // own attributes - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, relElem.first, "First"); - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, relElem.second, "Second"); - - // result - return o; - } - } - - public class AasUaEntityOperationVariable : AasUaEntitySubmodelElementBase - { - public AasUaEntityOperationVariable(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("OperationVariableType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:OperationVariable"); - } - - public NodeState CreateAddInstanceObject(NodeState parent, OperationVariable opvar) - { - // access - if (opvar == null || opvar.Value == null || opvar.Value.submodelElement == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + opvar.Value.submodelElement.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, opvar.Value.submodelElement); - - // own attributes - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(o, CreateMode.Instance, opvar.Value); - - // result - return o; - } - } - - public class AasUaEntityOperation : AasUaEntitySubmodelElementBase - { - public AasUaEntityOperation(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASOperationType", entityBuilder.AasTypes.SubmodelElement.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:Operation"); - - // indicate the Operation - this.entityBuilder.CreateAddMethodState(this.typeObject, "Operation", - inputArgs: null, - outputArgs: null, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent); - - // some elements - for (int i = 0; i < 2; i++) - { - var o2 = this.entityBuilder.CreateAddObject(this.typeObject, (i == 0) ? "in" : "out", ReferenceTypeIds.HasComponent, this.entityBuilder.AasTypes.OperationVariable.GetTypeObject().NodeId); - this.entityBuilder.AasTypes.OperationVariable.CreateAddInstanceObject(o2, null); - } - } - - public NodeState CreateAddInstanceObject(NodeState parent, Operation op) - { - // access - if (op == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + op.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId); - - // populate common attributes - base.PopulateInstanceObject(o, op); - - // own AAS attributes (in/out op vars) - for (int i = 0; i < 2; i++) - { - var opvarList = op[i]; - if (opvarList != null && opvarList.Count > 0) - { - var o2 = this.entityBuilder.CreateAddObject(o, (i == 0) ? "OperationInputVariables" : "OperationOutputVariables", - ReferenceTypeIds.HasComponent, /* TODO */ GetTypeObject().NodeId); - foreach (var opvar in opvarList) - if (opvar != null && opvar.Value != null) - this.entityBuilder.AasTypes.SubmodelWrapper.CreateAddElements(o2, CreateMode.Instance, opvar.Value); - } - } - - // create a method? - if (true) - { - var args = new List[] { new List(), new List() }; - for (int i = 0; i < 2; i++) - if (op[i] != null) - foreach (var opvar in op[i]) - { - // TODO: decide to from where the name comes - var name = "noname"; - - // TODO: description: get "en" version is appropriate? - LocalizedText desc = new LocalizedText(""); - - // TODO: parse UA data type out .. OK? - NodeId dataType = null; - if (opvar.Value != null && opvar.Value.submodelElement != null) - { - // better name .. but not best (see below) - if (opvar.Value.submodelElement.IdShort != null && opvar.Value.submodelElement.IdShort.Trim() != "") - name = "" + opvar.Value.submodelElement.IdShort; - - // TODO: description: get "en" version is appropriate? - desc = AasUaUtils.GetBestUaDescriptionFromAasDescription(opvar.Value.submodelElement.description); - - // currenty, only accept properties as in/out arguments. Only these have an XSD value type!! - var prop = opvar.Value.submodelElement as Property; - if (prop != null && prop.ValueType != null) - { - // TODO: this any better? - if (prop.IdShort != null && prop.IdShort.Trim() != "") - name = "" + prop.IdShort; - - // TODO: description: get "en" version is appropriate? - if (desc.Text == null || desc.Text == "") - desc = AasUaUtils.GetBestUaDescriptionFromAasDescription(opvar.Value.submodelElement.description); - - // try convert type - Type sharpType; - if (!AasUaUtils.AasValueTypeToUaDataType(prop.ValueType, out sharpType, out dataType)) - dataType = null; - } - } - if (dataType == null) - continue; - - var a = new Argument(name, dataType, -1, desc.Text ?? ""); - args[i].Add(a); - } - - var opmeth = this.entityBuilder.CreateAddMethodState(o, "Operation", - inputArgs: args[0].ToArray(), - outputArgs: args[1].ToArray(), - referenceTypeFromParentId: ReferenceTypeIds.HasComponent); - } - - // result - return o; - } - } - - public class AasUaEntityView : AasUaBaseEntity - { - public AasUaEntityView(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASViewType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:View"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId()); - - // add some elements - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(this.typeObject, CreateMode.Type, null, "SemanticId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - // contained elements - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "ContainedElement", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.View view = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - if (mode == CreateMode.Type) - { - - // create only containing element with generic name - var o = this.entityBuilder.CreateAddObject(parent, "View", ReferenceTypeIds.HasComponent, this.GetTypeNodeId(), modellingRule: modellingRule); - return o; - - } - else - { - // access - if (view == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "" + view.IdShort, ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, extraName: "View:" + view.IdShort); - - // register node record - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, view)); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, view); - // HasSemantics - this.entityBuilder.AasTypes.SemanticId.CreateAddInstanceObject(o, CreateMode.Instance, view.semanticId, "SemanticId"); - // HasDataSpecification - if (view.hasDataSpecification != null && view.hasDataSpecification.reference != null) - foreach (var ds in view.hasDataSpecification.reference) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ds, "DataSpecification"); - - // contained elements - for (int i = 0; i < view.Count; i++) - { - var cer = view[i]; - if (cer != null) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, cer, "ContainedElement"); - } - - // OK - return o; - } - } - } - - public class AasUaEntityConceptDictionary : AasUaBaseEntity - { - public AasUaEntityConceptDictionary(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASConceptDictionaryType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:ConceptDictionary"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId()); - - // add necessary type information - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - // Dictionary Entries - this.entityBuilder.CreateAddObject(this.typeObject, "DictionaryEntry", ReferenceTypeIds.HasComponent, this.entityBuilder.AasTypes.DictionaryEntryType.GetTypeNodeId(), modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.ConceptDictionary cdd = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - // Create whole object only if required - if (mode == CreateMode.Instance && cdd == null) - return null; - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, "ConceptDictionary", ReferenceTypeIds.HasComponent, GetTypeObject().NodeId, modellingRule: modellingRule); - - if (mode == CreateMode.Instance) - { - // access - if (cdd == null) - return null; - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, cdd); - } - - return o; - } - } - - public class AasUaEntityDataSpecification : AasUaBaseEntity - { - public AasUaEntityDataSpecification(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASDataSpecificationType", ObjectTypeIds.BaseObjectType, preferredTypeNumId, descriptionKey: "AAS:DataSpecification"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - } - - } - - public class AasUaEntityDataSpecificationIEC61360 : AasUaBaseEntity - { - public AasUaEntityDataSpecificationIEC61360(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("AASDataSpecificationIEC61360Type", this.entityBuilder.AasTypes.DataSpecification.GetTypeNodeId(), preferredTypeNumId, descriptionKey: "AAS:DataSpecificationIEC61360"); - - // very special rule here for the Identifiable - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObject, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Instance, - new AdminShell.Identification("URI", "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360"), - modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Instance, - new AdminShell.Administration("1", "0"), - modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - // add some more elements - this.entityBuilder.CreateAddPropertyState(this.typeObject, "PreferredName", DataTypeIds.LocalizedText, - value: null, defaultSettings: true, valueRank: 1, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "ShortName", DataTypeIds.String, value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Unit", DataTypeIds.String, value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.AasTypes.Reference.CreateAddElements(this.typeObject, CreateMode.Type, null, "UnitId", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "SourceOfDefinition", DataTypeIds.LocalizedText, - value: null, defaultSettings: true, valueRank: 1, modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Symbol", DataTypeIds.String, value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "DataType", DataTypeIds.String, value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "Definition", DataTypeIds.LocalizedText, - value: null, defaultSettings: true, valueRank: 1, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - - this.entityBuilder.CreateAddPropertyState(this.typeObject, "ValueFormat", DataTypeIds.String, value: null, defaultSettings: true, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, AdminShell.DataSpecificationIEC61360 ds = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - // for the sake of clarity, we're directly splitting cases - if (mode == CreateMode.Type) - { - // containing element (only) - var o = this.entityBuilder.CreateAddObject(parent, "DataSpecificationIEC61360", this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), GetTypeObject().NodeId, modellingRule: modellingRule); - return o; - } - else - { - // access - if (ds == null) - return null; - - // we can only provide minimal unique naming - var name = "DataSpecificationIEC61360"; - if (ds.shortName != null && this.entityBuilder.RootDataSpecifications != null) - name += "_" + ds.shortName; - - // containing element (depending on root folder) - NodeState o = null; - if (this.entityBuilder.RootDataSpecifications != null) - { - // under common folder - o = this.entityBuilder.CreateAddObject(this.entityBuilder.RootDataSpecifications, name, ReferenceTypeIds.Organizes, GetTypeObject().NodeId); - // link to this object - parent.AddReference(this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), false, o.NodeId); - } - else - { - // under parent - o = this.entityBuilder.CreateAddObject(parent, name, this.entityBuilder.AasTypes.HasAddIn.GetTypeNodeId(), GetTypeObject().NodeId); - } - - // add some elements - if (ds.preferredName != null && ds.preferredName.Count > 0) - this.entityBuilder.CreateAddPropertyState(o, "PreferredName", DataTypeIds.LocalizedText, - value: AasUaUtils.GetUaLocalizedTexts(ds.preferredName?.langString), defaultSettings: true, valueRank: 1); - - if (ds.shortName != null && ds.shortName.Count > 0) - this.entityBuilder.CreateAddPropertyState(o, "ShortName", DataTypeIds.LocalizedText, - value: AasUaUtils.GetUaLocalizedTexts(ds.shortName?.langString), defaultSettings: true, valueRank: 1); - - if (ds.unit != null) - this.entityBuilder.CreateAddPropertyState(o, "Unit", DataTypeIds.String, value: ds.unit, defaultSettings: true); - - if (ds.unitId != null) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, AdminShell.Reference.CreateNew(ds.unitId?.Keys), "UnitId"); - - if (ds.sourceOfDefinition != null) - this.entityBuilder.CreateAddPropertyState(o, "SourceOfDefinition", DataTypeIds.String, value: ds.sourceOfDefinition, defaultSettings: true); - - if (ds.symbol != null) - this.entityBuilder.CreateAddPropertyState(o, "Symbol", DataTypeIds.String, value: ds.symbol, defaultSettings: true); - - if (ds.dataType != null) - this.entityBuilder.CreateAddPropertyState(o, "DataType", DataTypeIds.String, value: ds.dataType, defaultSettings: true); - - if (ds.definition != null && ds.definition.Count > 0) - this.entityBuilder.CreateAddPropertyState(o, "Definition", DataTypeIds.LocalizedText, - value: AasUaUtils.GetUaLocalizedTexts(ds.definition?.langString), defaultSettings: true, valueRank: 1); - - if (ds.ValueFormat != null) - this.entityBuilder.CreateAddPropertyState(o, "ValueFormat", DataTypeIds.String, value: ds.ValueFormat, defaultSettings: true); - - // return - return o; - } - } - } - - public class AasUaEntityConceptDescription : AasUaBaseEntity - { - public NodeState typeObjectIrdi; - public NodeState typeObjectUri; - public NodeState typeObjectCustom; - - - public AasUaEntityConceptDescription(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - // TODO: make super classes for UriDictionaryEntryType.. - this.typeObjectIrdi = this.entityBuilder.CreateAddObjectType("AASIrdiConceptDescriptionType", this.entityBuilder.AasTypes.IrdiDictionaryEntryType.GetTypeNodeId(), 0, descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectIrdi, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - this.typeObjectUri = this.entityBuilder.CreateAddObjectType("AASUriConceptDescriptionType", this.entityBuilder.AasTypes.UriDictionaryEntryType.GetTypeNodeId(), 0, descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectUri, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - this.typeObjectCustom = this.entityBuilder.CreateAddObjectType("AASCustomConceptDescriptionType", this.entityBuilder.AasTypes.DictionaryEntryType.GetTypeNodeId(), 0, descriptionKey: "AAS:ConceptDescription"); - this.entityBuilder.AasTypes.HasInterface.CreateAddInstanceReference(this.typeObjectCustom, false, this.entityBuilder.AasTypes.IAASIdentifiableType.GetTypeNodeId()); - - // for each of them, add some elements - foreach (var o in new NodeState[] { this.typeObjectIrdi, this.typeObjectUri, this.typeObjectCustom }) - { - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Type); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // IsCaseOf - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Type, null, "IsCaseOf", modellingRule: AasUaNodeHelper.ModellingRule.Optional); - // HasDataSpecification - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Type, null, "DataSpecification", modellingRule: AasUaNodeHelper.ModellingRule.OptionalPlaceholder); - - // data specification is a child - this.entityBuilder.AasTypes.DataSpecificationIEC61360.CreateAddElements(o, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.MandatoryPlaceholder); - } - } - - public NodeState GetTypeObjectFor(AdminShell.Identification identification) - { - var to = this.typeObject; // shall be NULL - if (identification != null && identification.idType != null && identification.idType.Trim().ToUpper() == "URI") - to = this.typeObjectUri; - if (identification != null && identification.idType != null && identification.idType.Trim().ToUpper() == "IRDI") - to = this.typeObjectIrdi; - if (identification != null && identification.idType != null && identification.idType.Trim().ToUpper() == "CUSTOM") - to = this.typeObjectCustom; - return to; - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, ConceptDescription cd = null, AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None) - { - if (parent == null) - return null; - - // split directly because of complexity - if (mode == CreateMode.Type) - { - // not sure, if this will required, ever - return null; - } - else - { - // access - if (cd == null) - return null; - - // makeup name - var name = "ConceptDescription_" + Guid.NewGuid().ToString(); - - if (false) - { - // Conventional approach: build up a speaking name - // but: shall be target of "HasDictionaryEntry", therefore the __PURE__ identifications need to be the name! - if (cd.embeddedDataSpecification != null && cd.embeddedDataSpecification.dataSpecificationContent != null && cd.embeddedDataSpecification.dataSpecificationContent.dataSpecificationIEC61360 != null) - { - var ds = cd.embeddedDataSpecification.dataSpecificationContent.dataSpecificationIEC61360; - if (ds.shortName != null) - name = ds.shortName.GetDefaultStr(); - if (cd.identification != null) - name += "_" + cd.identification.ToString(); - } - name = AasUaUtils.ToOpcUaName(name); - } - else - { - // only identification (the type object will distinct between the id type) - if (cd.identification != null) - name = cd.identification.id; - } - - // containing element - var o = this.entityBuilder.CreateAddObject(parent, name, ReferenceTypeIds.HasComponent, this.GetTypeObjectFor(cd.identification)?.NodeId, modellingRule: modellingRule); - - // Referable - this.entityBuilder.AasTypes.Referable.CreateAddElements(o, CreateMode.Instance, cd); - // Identifiable - this.entityBuilder.AasTypes.Identification.CreateAddElements(o, CreateMode.Instance, cd.identification); - this.entityBuilder.AasTypes.Administration.CreateAddElements(o, CreateMode.Instance, cd.administration); - // IsCaseOf - if (cd.IsCaseOf != null) - foreach (var ico in cd.IsCaseOf) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, ico, "IsCaseOf"); - // HasDataSpecification - if (cd.embeddedDataSpecification != null && cd.embeddedDataSpecification.dataSpecification != null) - this.entityBuilder.AasTypes.Reference.CreateAddElements(o, CreateMode.Instance, cd.embeddedDataSpecification.dataSpecification, "DataSpecification"); - - // data specification is a child - if (cd.embeddedDataSpecification != null && cd.embeddedDataSpecification.dataSpecificationContent != null && cd.embeddedDataSpecification.dataSpecificationContent.dataSpecificationIEC61360 != null) - { - var dso = this.entityBuilder.AasTypes.DataSpecificationIEC61360.CreateAddElements(o, CreateMode.Instance, cd.embeddedDataSpecification.dataSpecificationContent.dataSpecificationIEC61360); - } - - // remeber CD as NodeRecord - this.entityBuilder.AddNodeRecord(new AasEntityBuilder.NodeRecord(o, cd.identification)); - - return o; - } - } - } - - // - // Elements from the UA spc - // - - public class AasUaNamespaceZeroEntity : AasUaBaseEntity - { - public AasUaNamespaceZeroEntity(AasEntityBuilder entityBuilder, uint presetNumId = 0) - : base(entityBuilder) - { - // just set node id based on existing knowledge - this.typeObjectId = new NodeId(presetNumId, 0); - } - } - - public class AasUaNamespaceZeroReference : AasUaBaseEntity - { - public AasUaNamespaceZeroReference(AasEntityBuilder entityBuilder, uint presetNumId = 0) - : base(entityBuilder) - { - // just set node id based on existing knowledge - this.typeObjectId = new NodeId(presetNumId, 0); - } - - public void CreateAddInstanceReference(NodeState source, bool isInverse, ExpandedNodeId target) - { - if (source != null && target != null && this.GetTypeNodeId() != null) - source.AddReference(this.GetTypeNodeId(), isInverse, target); - } - } - - // - // References - // - - public class AasUaReferenceHasAasReference : AasUaBaseEntity - { - public AasUaReferenceHasAasReference(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddReferenceType("AASReference", "AASReferencedBy", preferredTypeNumId, useZeroNS: false); - } - - public NodeState CreateAddInstanceReference(NodeState parent) - { - return null; - } - } - - - // - // Interfaces - // - - public class AasUaInterfaceAASIdentifiableType : AasUaBaseEntity - { - public AasUaInterfaceAASIdentifiableType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("IAASIdentifiableType", this.entityBuilder.AasTypes.IAASReferableType.GetTypeNodeId() /* ObjectTypeIds.BaseObjectType */, preferredTypeNumId, descriptionKey: "AAS:Identifiable"); - - // add some elements - this.entityBuilder.AasTypes.Identification.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Mandatory); - this.entityBuilder.AasTypes.Administration.CreateAddElements(this.typeObject, CreateMode.Type, modellingRule: AasUaNodeHelper.ModellingRule.Optional); - } - } - - public class AasUaInterfaceAASReferableType : AasUaBaseEntity - { - public AasUaInterfaceAASReferableType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // create type object - this.typeObject = this.entityBuilder.CreateAddObjectType("IAASReferableType", this.entityBuilder.AasTypes.BaseInterfaceType.GetTypeNodeId() /* ObjectTypeIds.BaseObjectType */, preferredTypeNumId, descriptionKey: "AAS:Referable"); - - // some elements - this.entityBuilder.AasTypes.Referable.CreateAddElements(this.typeObject, CreateMode.Type); - } - } -} diff --git a/src/AasxServerStandardBib/AasUaEntityFileType.cs b/src/AasxServerStandardBib/AasUaEntityFileType.cs deleted file mode 100644 index 18a8fe363..000000000 --- a/src/AasxServerStandardBib/AasUaEntityFileType.cs +++ /dev/null @@ -1,391 +0,0 @@ -/* -Copyright (c) 2018-2019 Festo AG & Co. KG -Author: Michael Hoffmeister - -This source code is licensed under the Apache License 2.0 (see LICENSE.txt). - -This source code may use other Open Source software components (see LICENSE.txt). -*/ - -using AdminShellNS; -using Opc.Ua; -using System; -using System.Collections.Generic; -using System.IO; - -namespace AasOpcUaServer -{ - public class AasUaPackageFileHandler - { - private AdminShellPackageEnv package = null; - private AasCore.Aas3_0.File file = null; - - private class PackageFileHandle - { - public UInt32 handle = 0; - public UInt64 filepos = 0; - public Stream packStream = null; - - public int UaMode = 0; - public bool IsRead = true; - public bool IsWrite = true; - - public PackageFileHandle() { } - public PackageFileHandle(UInt32 handle) - { - this.handle = handle; - } - } - - private Dictionary handles = new Dictionary(); - - public AasUaPackageFileHandler(AdminShellPackageEnv package, AasCore.Aas3_0.File file) - { - this.package = package; - this.file = file; - } - - private UInt32 GetMaxHandle() - { - UInt32 mh = 0; - foreach (var x in handles.Keys) - mh = Math.Max(x, mh); - return mh; - } - - public UInt32 Open(Byte mode) - { - // access file handle - if (this.package == null || this.file == null) - throw new InvalidOperationException("no admin-shell package or file"); - var nh = GetMaxHandle() + 1; - var fh = new PackageFileHandle(nh); - fh.packStream = package.GetLocalStreamFromPackage(file.Value); - if (fh.packStream == null) - throw new InvalidOperationException("no admin-shell package or file"); - handles.Add(nh, fh); - - // care about the particularities of write - fh.UaMode = mode; - fh.IsRead = ((mode & 0x01) > 0); - fh.IsWrite = ((mode & 0x02) > 0); - if ((mode & 0x04) > 0) - { - // Erase existing - fh.packStream.Seek(0, SeekOrigin.Begin); - fh.packStream.SetLength(0); - fh.packStream.Flush(); - } - if ((mode & 0x08) > 0) - { - // Append - fh.packStream.Seek(0, SeekOrigin.End); - fh.packStream.Flush(); - } - - // done - return nh; - } - - public long GetLength(UInt32 handle) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - var h = handles[handle]; - return h.packStream.Length; - } - - public void Close(UInt32 handle) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - handles.Remove(handle); - } - - public void SetPosition(UInt32 handle, UInt64 pos) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - var h = handles[handle]; - h.filepos = pos; - } - - public UInt64 GetPosition(UInt32 handle) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - if (this.package == null || this.file == null) - throw new InvalidOperationException("no admin-shell package or file"); - var h = handles[handle]; - return h.filepos; - } - - public Byte[] Read(UInt32 handle, UInt32 readlen) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - if (this.package == null || this.file == null) - throw new InvalidOperationException("no admin-shell package or file"); - var h = handles[handle]; - if (h.packStream == null) - throw new InvalidOperationException("no open stream"); - if (h.filepos >= (ulong)h.packStream.Length) - throw new InvalidOperationException("invalid file position"); - - // Finding: 4.194.304 Bytes as requested by the UA Expert is too much - // Reduce zu 16bit Size, to show suitablility also for small devices - readlen = Math.Min(readlen, (2 << 15) - 1); - - byte[] res = new byte[readlen]; - h.packStream.Seek((long)h.filepos, SeekOrigin.Begin); - var redd = h.packStream.Read(res, 0, (int)readlen); - h.filepos += (UInt64)redd; - return res; - } - - public void Write(UInt32 handle, Byte[] data) - { - if (!handles.ContainsKey(handle)) - throw new InvalidOperationException("handle is unknown"); - if (this.package == null || this.file == null) - throw new InvalidOperationException("no admin-shell package or file"); - var h = handles[handle]; - if (h.packStream == null) - throw new InvalidOperationException("no open stream"); - - h.packStream.Write(data, 0, data.Length); - h.filepos += (ulong)data.Length; - } - } - - public class AasUaEntityFileType : AasUaBaseEntity - { - private class InstanceData - { - public AasUaPackageFileHandler packHandler = null; - public MethodState mOpen, mClose, mRead, mWrite, mSetPosition, mGetPosition; - public PropertyState nodeOpenCount = null; - public PropertyState nodeSize = null; - - public void UpdateSize(UInt64 size) - { - if (nodeSize != null) - nodeSize.Value = size; - } - } - - public AasUaEntityFileType(AasEntityBuilder entityBuilder, uint preferredTypeNumId = 0) - : base(entityBuilder) - { - // do NOT create type object, as they shall be all there in the UA constants - } - - /// - /// Checks, if a FileType node is advisable for representing an AASX file .. - /// Shall be TRUE for local, existing files .. - /// - /// - public bool CheckSuitablity(AdminShellPackageEnv package, AasCore.Aas3_0.File file) - { - // trivial - if (package == null || file == null) - return false; - - // try get a stream .. - Stream s = null; - try - { - s = package.GetLocalStreamFromPackage(file.Value); - } - catch (Exception ex) - { - AdminShellNS.LogInternally.That.SilentlyIgnoredError(ex); - return false; - } - - // ok? - return s != null; - } - - public NodeState CreateAddElements(NodeState parent, CreateMode mode, - AdminShellPackageEnv package = null, AasCore.Aas3_0.File file = null) - { - // access - if (parent == null) - return null; - - // for sake of complexity, differentiate early - if (mode == CreateMode.Type) - { - var o = this.entityBuilder.CreateAddObject( - parent, mode, "File", ReferenceTypeIds.HasComponent, ObjectTypeIds.FileType); - return o; - } - else - { - if (package == null || file == null) - return null; - - var instData = new InstanceData(); - instData.packHandler = new AasUaPackageFileHandler(package, file); - - // containing element - var o = this.entityBuilder.CreateAddObject( - parent, mode, "File", ReferenceTypeIds.HasComponent, ObjectTypeIds.FileType); - - - // this first information is to provide a "off-the-shelf" size information; a Open() will re-new this - var fileLen = Convert.ToUInt64(package.GetStreamSizeFromPackage(file.Value)); - - // populate attributes from the spec - this.entityBuilder.CreateAddPropertyState(o, mode, "MimeType", - DataTypeIds.String, file.ContentType, ReferenceTypeIds.HasProperty, VariableTypeIds.PropertyType); - instData.nodeOpenCount = this.entityBuilder.CreateAddPropertyState(o, mode, "OpenCount", - DataTypeIds.UInt16, 0, ReferenceTypeIds.HasProperty, VariableTypeIds.PropertyType); - instData.nodeSize = this.entityBuilder.CreateAddPropertyState(o, mode, "Size", - DataTypeIds.UInt64, fileLen, ReferenceTypeIds.HasProperty, VariableTypeIds.PropertyType, - valueRank: -1); - this.entityBuilder.CreateAddPropertyState(o, mode, "UserWritable", - DataTypeIds.Boolean, true, ReferenceTypeIds.HasProperty, VariableTypeIds.PropertyType); - this.entityBuilder.CreateAddPropertyState(o, mode, "Writable", - DataTypeIds.Boolean, true, ReferenceTypeIds.HasProperty, VariableTypeIds.PropertyType); - - // Open - instData.mOpen = this.entityBuilder.CreateAddMethodState(o, mode, "Open", - inputArgs: new[] { - new Argument("Mode", DataTypeIds.Byte, -1, "") - }, - outputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, "") - }, referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_Open, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mOpen, instData); - - // Close - instData.mClose = this.entityBuilder.CreateAddMethodState(o, mode, "Close", - inputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, "") - }, - outputArgs: null, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_Close, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mClose, instData); - - // Read - instData.mRead = this.entityBuilder.CreateAddMethodState(o, mode, "Read", - inputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, ""), - new Argument("Length", DataTypeIds.Int32, -1, "") - }, - outputArgs: new[] { - new Argument("Data", DataTypeIds.ByteString, -1, "") - }, referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_Read, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mRead, instData); - - // Write - instData.mWrite = this.entityBuilder.CreateAddMethodState(o, mode, "Write", - inputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, ""), - new Argument("Data", DataTypeIds.ByteString, -1, "") - }, - outputArgs: null, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_Write, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mWrite, instData); - - // GetPosition - instData.mGetPosition = this.entityBuilder.CreateAddMethodState(o, mode, "GetPosition", - inputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, ""), - }, - outputArgs: new[] { - new Argument("Position", DataTypeIds.UInt64, -1, "") - }, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_GetPosition, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mGetPosition, instData); - - // SetPosition - instData.mSetPosition = this.entityBuilder.CreateAddMethodState(o, mode, "SetPosition", - inputArgs: new[] { - new Argument("FileHandle", DataTypeIds.UInt32, -1, ""), - new Argument("Position", DataTypeIds.UInt64, -1, "") - }, - outputArgs: null, - referenceTypeFromParentId: ReferenceTypeIds.HasComponent, - methodDeclarationId: MethodIds.FileType_SetPosition, onCalled: this.OnMethodCalled); - - this.entityBuilder.AddNodeStateAnnotation(instData.mSetPosition, instData); - - // result - return o; - } - } - - private ServiceResult OnMethodCalled( - ISystemContext context, - MethodState method, - IList inputArguments, - IList outputArguments) - { - var instData = this.entityBuilder.FindNoteStateAnnotation(method); - if (instData == null || instData.packHandler == null) - return new ServiceResult(StatusCodes.BadInvalidArgument); - - try - { - if (method == instData.mOpen) - { - var fh = instData.packHandler.Open((byte)inputArguments[0]); - instData.UpdateSize(Convert.ToUInt64(instData.packHandler.GetLength(fh))); - outputArguments[0] = fh; - } - - if (method == instData.mClose) - { - instData.packHandler.Close((UInt32)inputArguments[0]); - } - - if (method == instData.mSetPosition) - { - instData.packHandler.SetPosition((UInt32)inputArguments[0], (UInt64)inputArguments[1]); - } - - if (method == instData.mGetPosition) - { - outputArguments[0] = instData.packHandler.GetPosition((UInt32)inputArguments[0]); - } - - if (method == instData.mRead) - { - var data = instData.packHandler.Read( - Convert.ToUInt32(inputArguments[0]), Convert.ToUInt32(inputArguments[1])); - outputArguments[0] = data; - } - - if (method == instData.mWrite) - { - var fh = Convert.ToUInt32(inputArguments[0]); - instData.packHandler.Write(fh, (byte[])inputArguments[1]); - instData.UpdateSize(Convert.ToUInt64(instData.packHandler.GetLength(fh))); - } - } - catch (Exception ex) - { - AdminShellNS.LogInternally.That.Error(ex, "The method could not be executed."); - - // treat every exception the same - return new ServiceResult(StatusCodes.BadInvalidArgument); - } - - return new ServiceResult(StatusCodes.Good); - } - - } -} diff --git a/src/AasxServerStandardBib/AasUaNodeHelper.cs b/src/AasxServerStandardBib/AasUaNodeHelper.cs deleted file mode 100644 index 99ad83926..000000000 --- a/src/AasxServerStandardBib/AasUaNodeHelper.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Opc.Ua; - -namespace AasOpcUaServer -{ - public class AasUaNodeHelper - { - /// - /// 4. The cardinality of an association or aggregation is specified via OPC Modelling rules. - /// The OPC modelling rule “Optional” is used if the cardinality is Zero or 1. - /// The OPC modelling rule “Mandatory” is used if the cardinality is One. - /// The OPC Modelling rule “OptionalPlaceholder” is used if the cardinality is zero, one or more than one element. - /// The OPC Modelling rule “MandatoryPlaceholder” ” is used if the cardinality is one or more than one element. - /// - public enum ModellingRule { None, Optional, OptionalPlaceholder, Mandatory, MandatoryPlaceholder } - - /// - /// Try find out the Description for a certain AAS literal/ refSemantics - /// - public static LocalizedText SetLocalizedTextWithDescription(LocalizedText l, string key) - { - var dk = AasEntityDescriptions.LookupDescription(key); - if (key != null) - l = new LocalizedText("en", dk); - return l; - } - - /// - /// Appply modelling rule to an arbitrary node - /// - public static NodeState CheckSetModellingRule(ModellingRule modellingRule, NodeState o) - { - if (o == null || modellingRule == ModellingRule.None) - return o; - if (modellingRule == ModellingRule.Optional) - o.AddReference(ReferenceTypeIds.HasModellingRule, false, ObjectIds.ModellingRule_Optional); - if (modellingRule == ModellingRule.OptionalPlaceholder) - o.AddReference(ReferenceTypeIds.HasModellingRule, false, ObjectIds.ModellingRule_OptionalPlaceholder); - if (modellingRule == ModellingRule.Mandatory) - o.AddReference(ReferenceTypeIds.HasModellingRule, false, ObjectIds.ModellingRule_Mandatory); - if (modellingRule == ModellingRule.MandatoryPlaceholder) - o.AddReference(ReferenceTypeIds.HasModellingRule, false, ObjectIds.ModellingRule_MandatoryPlaceholder); - return o; - } - - /// - /// Helper to create an ObjectType-Node. Note: __NO__ NodeId is created by the default! Must be done by outer functionality!! - /// - /// Name displayed in the node tree - /// Base class or similar - /// Preset the NodeId - /// Lookup a Description on AAS literal/ refSemantics - /// Modeling Rule, if not None - /// THe node - public static BaseObjectTypeState CreateObjectType( - string browseDisplayName, - NodeId superTypeId, - NodeId presetNodeId = null, - string descriptionKey = null, - ModellingRule modellingRule = ModellingRule.None) - { - var x = new BaseObjectTypeState(); - x.BrowseName = "" + browseDisplayName; - x.DisplayName = "" + browseDisplayName; - x.Description = new LocalizedText("en", browseDisplayName); - x.Description = SetLocalizedTextWithDescription(x.Description, descriptionKey); - x.SuperTypeId = superTypeId; - if (presetNodeId != null) - x.NodeId = presetNodeId; - CheckSetModellingRule(modellingRule, x); - return x; - } - - /// - /// Helper to create an ReferenceType-Node. Note: __NO__ NodeId is created by the default! Must be done by outer functionality!! - /// - /// Name displayed in the node tree - /// - /// Preset the NodeId - /// Preset the NodeId - /// - public static ReferenceTypeState CreateReferenceType( - string browseDisplayName, - string inverseName, - NodeId superTypeId, - NodeId presetNodeId = null) - { - // create node itself - var x = new ReferenceTypeState(); - x.BrowseName = browseDisplayName; - x.DisplayName = browseDisplayName; - x.InverseName = inverseName; - x.Symmetric = false; - x.IsAbstract = false; - x.SuperTypeId = superTypeId; - if (presetNodeId != null) - x.NodeId = presetNodeId; - return x; - } - - /// - /// Helper to create an Object-Node. Note: __NO__ NodeId is created by the default! Must be done by outer functionality!! - /// - /// Parent node - /// Name displayed in the node tree - /// Type of the Object - /// Modeling Rule, if not None - /// The node - public static BaseObjectState CreateObject( - NodeState parent, - string browseDisplayName, - NodeId typeDefinitionId = null, - AasUaNodeHelper.ModellingRule modellingRule = AasUaNodeHelper.ModellingRule.None, - string extraName = null) - { - var x = new BaseObjectState(parent); - x.BrowseName = "" + browseDisplayName; - x.DisplayName = "" + browseDisplayName; - if (extraName != null) - x.DisplayName = "" + extraName; - x.Description = new LocalizedText("en", browseDisplayName); - if (typeDefinitionId != null) - x.TypeDefinitionId = typeDefinitionId; - CheckSetModellingRule(modellingRule, x); - return x; - } - - } -} diff --git a/src/AasxServerStandardBib/AasUaUtils.cs b/src/AasxServerStandardBib/AasUaUtils.cs deleted file mode 100644 index 0313d6457..000000000 --- a/src/AasxServerStandardBib/AasUaUtils.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Opc.Ua; -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace AasOpcUaServer -{ - public class AasUaUtils - { - public static string ToOpcUaName(string input) - { - var clean = Regex.Replace(input, @"[^a-zA-Z0-9\-_]", "_"); - while (true) - { - var len0 = clean.Length; - clean = clean.Replace("__", "_"); - if (len0 == clean.Length) - break; - } - return clean; - } - - public static string ToOpcUaReference(Reference refid) - { - if (refid == null || refid.Keys == null || refid.Keys.Count == 0) - return null; - - var semstr = ""; - foreach (var k in refid.Keys) - { - if (semstr != "") - semstr += ","; - semstr += String.Format("({0}){1}", - k.Type, k.Value); - } - - return semstr; - } - - - public static List ToOpcUaReferenceList(Reference refid) - { - if (refid == null || refid.Keys == null || refid.Keys.Count == 0) - return null; - - var res = new List(); - foreach (var k in refid.Keys) - { - res.Add(String.Format("{0}", k.Value)); - } - - return res; - } - - public static LocalizedText[] GetUaLocalizedTexts(List ls) - { - if (ls == null || ls.Count < 1) - return new LocalizedText[] { new LocalizedText("", "") }; - var res = new LocalizedText[ls.Count]; - for (int i = 0; i < ls.Count; i++) - res[i] = new LocalizedText(ls[i].Language, ls[i].Text); - return res; - } - - public static LocalizedText GetBestUaDescriptionFromAasDescription(List desc) - { - var res = new LocalizedText("", ""); - if (desc != null && desc != null) - { - var found = false; - foreach (var ls in desc) - if (!found || ls.Language.Trim().ToLower().StartsWith("en")) - { - found = true; - res = new LocalizedText(ls.Language, ls.Text); - } - } - return res; - } - - public static bool AasValueTypeToUaDataType(string valueType, out Type sharpType, out NodeId dataTypeId) - { - // defaults - sharpType = "".GetType(); - dataTypeId = DataTypeIds.String; - if (valueType == null) - return false; - - // parse - var vt = valueType.ToLower().Trim(); - if (vt == "boolean") - { - sharpType = typeof(bool); - dataTypeId = DataTypeIds.Boolean; - return true; - } - else if (vt == "datetime" || vt == "datetimestamp" || vt == "time") - { - sharpType = typeof(Int64); - dataTypeId = DataTypeIds.DateTime; - return true; - } - else if (vt == "decimal" || vt == "integer" || vt == "long" || vt == "nonpositiveinteger" || vt == "negativeinteger") - { - sharpType = typeof(Int64); - dataTypeId = DataTypeIds.Int64; - return true; - } - else if (vt == "int") - { - sharpType = typeof(Int32); - dataTypeId = DataTypeIds.Int32; - return true; - } - else if (vt == "short") - { - sharpType = typeof(Int16); - dataTypeId = DataTypeIds.Int16; - return true; - } - else if (vt == "byte") - { - sharpType = typeof(SByte); - dataTypeId = DataTypeIds.Byte; - return true; - } - else if (vt == "nonnegativeinteger" || vt == "positiveinteger" || vt == "unsignedlong") - { - sharpType = typeof(UInt64); - dataTypeId = DataTypeIds.UInt64; - return true; - } - else if (vt == "unsignedint") - { - sharpType = typeof(UInt32); - dataTypeId = DataTypeIds.UInt32; - return true; - } - else if (vt == "unsignedshort") - { - sharpType = typeof(UInt16); - dataTypeId = DataTypeIds.UInt16; - return true; - } - else if (vt == "unsignedbyte") - { - sharpType = typeof(Byte); - dataTypeId = DataTypeIds.Byte; - return true; - } - else if (vt == "double") - { - sharpType = typeof(double); - dataTypeId = DataTypeIds.Double; - return true; - } - else if (vt == "float") - { - sharpType = typeof(float); - dataTypeId = DataTypeIds.Float; - return true; - } - else if (vt == "string") - { - sharpType = typeof(string); - dataTypeId = DataTypeIds.String; - return true; - } - - return false; - } - } -} diff --git a/src/AasxServerStandardBib/AasxHttpContextHelper.cs b/src/AasxServerStandardBib/AasxHttpContextHelper.cs index 94fd7a946..249c8af48 100644 --- a/src/AasxServerStandardBib/AasxHttpContextHelper.cs +++ b/src/AasxServerStandardBib/AasxHttpContextHelper.cs @@ -1,5 +1,4 @@ - -using AasxServer; +using AasxServer; using AdminShellNS; using Extensions; using Grapevine.Interfaces.Server; @@ -56,7 +55,7 @@ public class AasxHttpContextHelper public bool PathEndsWith(string path, string tag) { - return path.Trim().ToLower().TrimEnd(new char[] { '/' }).EndsWith(tag); + return path.Trim().ToLower().TrimEnd(new[] {'/'}).EndsWith(tag); } public bool PathEndsWith(Grapevine.Interfaces.Server.IHttpContext context, string tag) @@ -93,20 +92,22 @@ public List CreateHandlesFromQueryString(System.Co try { var k = kr.Trim().ToLower(); - var v = queryStrings[k]; + var v = queryStrings[ k ]; if (k.StartsWith("q") && k.Length > 1 && v.Contains(',')) { var vl = v.Split(','); if (vl.Length == 2) { //var id = new IIdentifiable(vl[1]); - var id = vl[1]; + var id = vl[ 1 ]; var h = new AasxHttpHandleIdentification(id, "@" + k); res.Add(h); } } } - catch { } + catch + { + } } // done @@ -131,15 +132,15 @@ public List CreateHandlesFromRawUrl(string rawUrl) // try make a Regex wonder, again var m = Regex.Match(query, @"(\s*([^&]+)(&|))+"); - if (m.Success && m.Groups.Count >= 3 && m.Groups[2].Captures != null) - foreach (var cp in m.Groups[2].Captures) + if (m.Success && m.Groups.Count >= 3 && m.Groups[ 2 ].Captures != null) + foreach (var cp in m.Groups[ 2 ].Captures) { var m2 = Regex.Match(cp.ToString(), @"\s*(\w+)\s*=\s*([^,]+),(.+)$"); if (m2.Success && m2.Groups.Count >= 4) { - var k = m2.Groups[1].ToString(); - var idt = m2.Groups[2].ToString(); - var ids = m2.Groups[3].ToString(); + var k = m2.Groups[ 1 ].ToString(); + var idt = m2.Groups[ 2 ].ToString(); + var ids = m2.Groups[ 3 ].ToString(); //var id = new IIdentifiable(ids); var id = ids; @@ -171,11 +172,11 @@ public FindAasReturn FindAAS(string aasid, System.Collections.Specialized.NameVa if (i > Packages.Length) return null; - if (Packages[i] == null || Packages[i].AasEnv == null || Packages[i].AasEnv.AssetAdministrationShells == null - || Packages[i].AasEnv.AssetAdministrationShells.Count < 1) + if (Packages[ i ] == null || Packages[ i ].AasEnv == null || Packages[ i ].AasEnv.AssetAdministrationShells == null + || Packages[ i ].AasEnv.AssetAdministrationShells.Count < 1) return null; - findAasReturn.aas = Packages[i].AasEnv.AssetAdministrationShells[0]; + findAasReturn.aas = Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ]; findAasReturn.iPackage = i; } else @@ -183,18 +184,18 @@ public FindAasReturn FindAAS(string aasid, System.Collections.Specialized.NameVa // Name if (aasid == "id") { - findAasReturn.aas = Packages[0].AasEnv.AssetAdministrationShells[0]; + findAasReturn.aas = Packages[ 0 ].AasEnv.AssetAdministrationShells[ 0 ]; findAasReturn.iPackage = 0; } else { for (int i = 0; i < Packages.Length; i++) { - if (Packages[i] != null) + if (Packages[ i ] != null) { - if (Packages[i].AasEnv.AssetAdministrationShells[0].IdShort == aasid) + if (Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ].IdShort == aasid) { - findAasReturn.aas = Packages[i].AasEnv.AssetAdministrationShells[0]; + findAasReturn.aas = Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ]; findAasReturn.iPackage = i; break; } @@ -226,10 +227,11 @@ public FindAasReturn FindAAS(string aasid, System.Collections.Specialized.NameVa */ } - public IReference FindSubmodelRefWithinAas(FindAasReturn findAasReturn, string smid, System.Collections.Specialized.NameValueCollection queryStrings = null, string rawUrl = null) + public IReference FindSubmodelRefWithinAas(FindAasReturn findAasReturn, string smid, System.Collections.Specialized.NameValueCollection queryStrings = null, + string rawUrl = null) { // trivial - if (Packages[findAasReturn.iPackage] == null || Packages[findAasReturn.iPackage].AasEnv == null || findAasReturn.aas == null || smid == null || smid.Trim() == "") + if (Packages[ findAasReturn.iPackage ] == null || Packages[ findAasReturn.iPackage ].AasEnv == null || findAasReturn.aas == null || smid == null || smid.Trim() == "") return null; // via handle @@ -246,7 +248,7 @@ public IReference FindSubmodelRefWithinAas(FindAasReturn findAasReturn, string s } else { - var sm = this.Packages[findAasReturn.iPackage].AasEnv.FindSubmodel(smref); + var sm = this.Packages[ findAasReturn.iPackage ].AasEnv.FindSubmodel(smref); if (sm != null && sm.IdShort != null && sm.IdShort.Trim().ToLower() == smid.Trim().ToLower()) return smref; } @@ -256,23 +258,24 @@ public IReference FindSubmodelRefWithinAas(FindAasReturn findAasReturn, string s return null; } - public ISubmodel FindSubmodelWithinAas(FindAasReturn findAasReturn, string smid, System.Collections.Specialized.NameValueCollection queryStrings = null, string rawUrl = null) + public ISubmodel FindSubmodelWithinAas(FindAasReturn findAasReturn, string smid, System.Collections.Specialized.NameValueCollection queryStrings = null, + string rawUrl = null) { // trivial - if (Packages[findAasReturn.iPackage] == null || Packages[findAasReturn.iPackage].AasEnv == null || findAasReturn.aas == null || smid == null || smid.Trim() == "") + if (Packages[ findAasReturn.iPackage ] == null || Packages[ findAasReturn.iPackage ].AasEnv == null || findAasReturn.aas == null || smid == null || smid.Trim() == "") return null; // via handle var specialHandles = this.CreateHandlesFromRawUrl(rawUrl); var handleId = IdRefHandleStore.ResolveSpecific(smid, specialHandles); if (handleId != null && handleId.identification != null) - return Packages[findAasReturn.iPackage].AasEnv.FindSubmodelById(handleId.identification); + return Packages[ findAasReturn.iPackage ].AasEnv.FindSubmodelById(handleId.identification); // no, iterate & find foreach (var smref in findAasReturn.aas.Submodels) { - var sm = this.Packages[findAasReturn.iPackage].AasEnv.FindSubmodel(smref); + var sm = this.Packages[ findAasReturn.iPackage ].AasEnv.FindSubmodel(smref); if (sm != null && sm.IdShort != null && sm.IdShort.Trim().ToLower() == smid.Trim().ToLower()) return sm; } @@ -298,11 +301,11 @@ public ISubmodel FindSubmodelWithinAas(string aasid, string smid, System.Collect if (i > Packages.Length) return null; - if (Packages[i] == null || Packages[i].AasEnv == null || Packages[i].AasEnv.AssetAdministrationShells == null - || Packages[i].AasEnv.AssetAdministrationShells.Count < 1) + if (Packages[ i ] == null || Packages[ i ].AasEnv == null || Packages[ i ].AasEnv.AssetAdministrationShells == null + || Packages[ i ].AasEnv.AssetAdministrationShells.Count < 1) return null; - aas = Packages[i].AasEnv.AssetAdministrationShells[0]; + aas = Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ]; iPackage = i; } else @@ -310,18 +313,18 @@ public ISubmodel FindSubmodelWithinAas(string aasid, string smid, System.Collect // Name if (aasid == "id") { - aas = Packages[0].AasEnv.AssetAdministrationShells[0]; + aas = Packages[ 0 ].AasEnv.AssetAdministrationShells[ 0 ]; iPackage = 0; } else { for (int i = 0; i < Packages.Length; i++) { - if (Packages[i] != null) + if (Packages[ i ] != null) { - if (Packages[i].AasEnv.AssetAdministrationShells[0].IdShort == aasid) + if (Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ].IdShort == aasid) { - aas = Packages[i].AasEnv.AssetAdministrationShells[0]; + aas = Packages[ i ].AasEnv.AssetAdministrationShells[ 0 ]; iPackage = i; break; } @@ -337,7 +340,7 @@ public ISubmodel FindSubmodelWithinAas(string aasid, string smid, System.Collect foreach (var smref in aas.Submodels) { - var sm = this.Packages[iPackage].AasEnv.FindSubmodel(smref); + var sm = this.Packages[ iPackage ].AasEnv.FindSubmodel(smref); if (sm != null && sm.IdShort != null && sm.IdShort.Trim().ToLower() == smid.Trim().ToLower()) return sm; } @@ -347,21 +350,20 @@ public ISubmodel FindSubmodelWithinAas(string aasid, string smid, System.Collect } - public ISubmodel FindSubmodelWithoutAas(string smid, System.Collections.Specialized.NameValueCollection queryStrings = null, string rawUrl = null) { // trivial - if (Packages[0] == null || Packages[0].AasEnv == null || smid == null || smid.Trim() == "") + if (Packages[ 0 ] == null || Packages[ 0 ].AasEnv == null || smid == null || smid.Trim() == "") return null; // via handle var specialHandles = this.CreateHandlesFromRawUrl(rawUrl); var handleId = IdRefHandleStore.ResolveSpecific(smid, specialHandles); if (handleId != null && handleId.identification != null) - return Packages[0].AasEnv.FindSubmodelById(handleId.identification); + return Packages[ 0 ].AasEnv.FindSubmodelById(handleId.identification); // no, iterate & find - foreach (var sm in this.Packages[0].AasEnv.Submodels) + foreach (var sm in this.Packages[ 0 ].AasEnv.Submodels) { if (sm != null && sm.IdShort != null && sm.IdShort.Trim().ToLower() == smid.Trim().ToLower()) return sm; @@ -371,20 +373,21 @@ public ISubmodel FindSubmodelWithoutAas(string smid, System.Collections.Speciali return null; } - public IConceptDescription FindCdWithoutAas(FindAasReturn findAasReturn, string cdid, System.Collections.Specialized.NameValueCollection queryStrings = null, string rawUrl = null) + public IConceptDescription FindCdWithoutAas(FindAasReturn findAasReturn, string cdid, System.Collections.Specialized.NameValueCollection queryStrings = null, + string rawUrl = null) { // trivial - if (Packages[findAasReturn.iPackage] == null || Packages[findAasReturn.iPackage].AasEnv == null || findAasReturn.aas == null || cdid == null || cdid.Trim() == "") + if (Packages[ findAasReturn.iPackage ] == null || Packages[ findAasReturn.iPackage ].AasEnv == null || findAasReturn.aas == null || cdid == null || cdid.Trim() == "") return null; // via handle var specialHandles = this.CreateHandlesFromRawUrl(rawUrl); var handleId = IdRefHandleStore.ResolveSpecific(cdid, specialHandles); if (handleId != null && handleId.identification != null) - return Packages[findAasReturn.iPackage].AasEnv.FindConceptDescriptionById(handleId.identification); + return Packages[ findAasReturn.iPackage ].AasEnv.FindConceptDescriptionById(handleId.identification); // no, iterate & find - foreach (var cd in Packages[findAasReturn.iPackage].AasEnv.ConceptDescriptions) + foreach (var cd in Packages[ findAasReturn.iPackage ].AasEnv.ConceptDescriptions) { if (cd.IdShort != null && cd.IdShort.Trim().ToLower() == cdid.Trim().ToLower()) return cd; @@ -420,7 +423,7 @@ public FindSubmodelElementResult FindSubmodelElement(IReferable parent, List= 0 && jsonld[k] != '}' && jsonld[k] != ']') + while (k >= 0 && jsonld[ k ] != '}' && jsonld[ k ] != ']') { k--; } - #pragma warning disable format - jsonld = jsonld.Substring(0, k+1); +#pragma warning disable format + jsonld = jsonld.Substring(0, k + 1); jsonld += ",\r\n" + " \"id\": \"" + id + "\"\r\n}\r\n"; jsonld = "\"doc\": " + jsonld; jsonld = "{\r\n\r\n" + header + jsonld + "\r\n\r\n}\r\n"; - #pragma warning restore format +#pragma warning restore format return jsonld; } + protected static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext context, object obj, IContractResolver contractResolver = null) { var queryString = context.Request.QueryString; - string refresh = queryString["refresh"]; + string refresh = queryString[ "refresh" ]; if (refresh != null && refresh != "") { context.Response.Headers.Remove("Refresh"); context.Response.Headers.Add("Refresh", refresh); } - string jsonld = queryString["jsonld"]; - string vc = queryString["vc"]; + + string jsonld = queryString[ "jsonld" ]; + string vc = queryString[ "vc" ]; var settings = new JsonSerializerSettings(); if (contractResolver != null) @@ -705,6 +719,7 @@ protected static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext { error = true; } + if (!error) { json = response.Content.ReadAsStringAsync().Result; @@ -729,16 +744,15 @@ protected static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext { if (kvp.Key.Equals("AAS")) { - value["AAS"] = Jsonization.Serialize.ToJsonObject((AssetAdministrationShell)kvp.Value); + value[ "AAS" ] = Jsonization.Serialize.ToJsonObject((AssetAdministrationShell) kvp.Value); } else if (kvp.Key.Equals("Asset")) { - value["AssetInformation"] = Jsonization.Serialize.ToJsonObject((AssetInformation)kvp.Value); + value[ "AssetInformation" ] = Jsonization.Serialize.ToJsonObject((AssetInformation) kvp.Value); } } json = value.ToString(); - } var buffer = context.Request.ContentEncoding.GetBytes(json); @@ -755,7 +769,7 @@ protected static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext protected static void SendTextResponse(Grapevine.Interfaces.Server.IHttpContext context, string txt, string mimeType = null) { var queryString = context.Request.QueryString; - string refresh = queryString["refresh"]; + string refresh = queryString[ "refresh" ]; if (refresh != null && refresh != "") { context.Response.Headers.Remove("Refresh"); @@ -797,7 +811,6 @@ protected static void SendRedirectResponse(Grapevine.Interfaces.Server.IHttpCont context.Response.SendResponse(HttpStatusCode.TemporaryRedirect, redirectUrl); } - #endregion #region AAS and Asset @@ -862,7 +875,7 @@ public void EvalGetAasEnv(IHttpContext context, string aasid) res.confirm = "Authorization = " + accessrights; } - if (this.Packages[0] == null || this.Packages[0].AasEnv == null) + if (this.Packages[ 0 ] == null || this.Packages[ 0 ].AasEnv == null) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -880,8 +893,8 @@ public void EvalGetAasEnv(IHttpContext context, string aasid) AasCore.Aas3_0.Environment copyenv = new AasCore.Aas3_0.Environment(); try { - var sourceEnvironment = Packages[findAasReturn.iPackage].AasEnv; - var aasList = new List() { findAasReturn.aas }; + var sourceEnvironment = Packages[ findAasReturn.iPackage ].AasEnv; + var aasList = new List() {findAasReturn.aas}; copyenv = copyenv.CreateFromExistingEnvironment(sourceEnvironment, aasList); } catch (Exception ex) @@ -910,6 +923,7 @@ public void EvalGetAasEnv(IHttpContext context, string aasid) jsonwriter.Close(); } } + if (PathEndsWith(context, "aasenvjson")) { // result @@ -949,7 +963,7 @@ public void EvalGetAasThumbnail(IHttpContext context, string aasid) res.confirm = "Authorization = " + accessrights; } - if (this.Packages[0] == null) + if (this.Packages[ 0 ] == null) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -966,7 +980,7 @@ public void EvalGetAasThumbnail(IHttpContext context, string aasid) // access the thumbnail // Note: in this version, the thumbnail is not specific to the AAS, but maybe in later versions ;-) Uri thumbUri = null; - var thumbStream = this.Packages[findAasReturn.iPackage].GetLocalThumbnailStream(ref thumbUri); + var thumbStream = this.Packages[ findAasReturn.iPackage ].GetLocalThumbnailStream(ref thumbUri); if (thumbStream == null) { context.Response.SendResponse(HttpStatusCode.NotFound, $"No thumbnail available in package."); @@ -1030,13 +1044,13 @@ public void EvalPutAas(IHttpContext context) int emptyPackageIndex = -1; for (int envi = 0; envi < this.Packages.Length; envi++) { - if (this.Packages[envi] != null) + if (this.Packages[ envi ] != null) { - var existingAas = this.Packages[envi].AasEnv.FindAasById(aas.Id); + var existingAas = this.Packages[ envi ].AasEnv.FindAasById(aas.Id); if (existingAas != null) { - this.Packages[envi].AasEnv.AssetAdministrationShells.Remove(existingAas); - this.Packages[envi].AasEnv.AssetAdministrationShells.Add(aas); + this.Packages[ envi ].AasEnv.AssetAdministrationShells.Remove(existingAas); + this.Packages[ envi ].AasEnv.AssetAdministrationShells.Add(aas); SendTextResponse(context, "OK (update, index=" + envi + ")"); return; } @@ -1053,8 +1067,8 @@ public void EvalPutAas(IHttpContext context) if (emptyPackageAvailable) { - this.Packages[emptyPackageIndex] = new AdminShellPackageEnv(); - this.Packages[emptyPackageIndex].AasEnv.AssetAdministrationShells.Add(aas); + this.Packages[ emptyPackageIndex ] = new AdminShellPackageEnv(); + this.Packages[ emptyPackageIndex ].AasEnv.AssetAdministrationShells.Add(aas); SendTextResponse(context, "OK (new, index=" + emptyPackageIndex + ")"); return; } @@ -1159,7 +1173,7 @@ public void EvalPutAasxOnServer(IHttpContext context) string aasIdShort = ""; try { - aasIdShort = aasEnv.AasEnv.AssetAdministrationShells[0].IdShort; + aasIdShort = aasEnv.AasEnv.AssetAdministrationShells[ 0 ].IdShort; } catch (Exception ex) { @@ -1174,23 +1188,24 @@ public void EvalPutAasxOnServer(IHttpContext context) { for (int envi = 0; envi < this.Packages.Length; envi++) { - if (this.Packages[envi] == null) + if (this.Packages[ envi ] == null) { - this.Packages[envi] = aasEnv; - Program.envFileName[envi] = file.path; + this.Packages[ envi ] = aasEnv; + Program.envFileName[ envi ] = file.path; context.Response.StatusCode = HttpStatusCode.Ok; SendTextResponse(context, "OK (new, index=" + envi + ")"); return; } } + context.Response.StatusCode = HttpStatusCode.NotFound; SendTextResponse(context, "Failed: Server used to capacity."); return; } else { - Packages[findAasReturn.iPackage] = aasEnv; - Program.envFileName[findAasReturn.iPackage] = file.path; + Packages[ findAasReturn.iPackage ] = aasEnv; + Program.envFileName[ findAasReturn.iPackage ] = file.path; context.Response.StatusCode = HttpStatusCode.Ok; SendTextResponse(context, "OK (update, index=" + findAasReturn.iPackage + ")"); return; @@ -1244,8 +1259,8 @@ public void EvalPutAasxToFilesystem(IHttpContext context, string aasid) { try { - Packages[findAasReturn.iPackage].SaveAs(file.path, false, AdminShellPackageEnv.SerializationFormat.Json, null); - Program.envFileName[findAasReturn.iPackage] = file.path; + Packages[ findAasReturn.iPackage ].SaveAs(file.path, false, AdminShellPackageEnv.SerializationFormat.Json, null); + Program.envFileName[ findAasReturn.iPackage ] = file.path; context.Response.StatusCode = HttpStatusCode.Ok; SendTextResponse(context, "OK (saved)"); return; @@ -1271,7 +1286,7 @@ public void EvalPutAasxReplacePackage(IHttpContext context, string aasid) { accessrights = SecurityCheck(context, ref index); - var aas = Program.env[aasInfo.iPackage].AasEnv.AssetAdministrationShells[0]; + var aas = Program.env[ aasInfo.iPackage ].AasEnv.AssetAdministrationShells[ 0 ]; if (!checkAccessRights(context, accessrights, "/aasx", "UPDATE", "", "aas", aas)) { return; @@ -1310,7 +1325,7 @@ public void EvalPutAasxReplacePackage(IHttpContext context, string aasid) } */ - var packFn = Packages[packIndex].Filename; + var packFn = Packages[ packIndex ].Filename; Console.WriteLine($"Will replace AASX package on server: {packFn}"); // make temp file @@ -1332,7 +1347,7 @@ public void EvalPutAasxReplacePackage(IHttpContext context, string aasid) try { // free to overwrite - Packages[packIndex].Close(); + Packages[ packIndex ].Close(); // copy to back (rename experienced to be more error-prone) System.IO.File.Copy(packFn, packFn + ".bak", overwrite: true); @@ -1347,7 +1362,7 @@ public void EvalPutAasxReplacePackage(IHttpContext context, string aasid) try { // replace loaded original when saving - packFn = Program.envFileName[packIndex]; + packFn = Program.envFileName[ packIndex ]; Console.WriteLine($"Replace original AASX package on server: {packFn}"); // copy into same location @@ -1356,7 +1371,7 @@ public void EvalPutAasxReplacePackage(IHttpContext context, string aasid) // open again var newAasx = new AdminShellPackageEnv(packFn, true); if (newAasx != null) - Packages[packIndex] = newAasx; + Packages[ packIndex ] = newAasx; else { context.Response.SendResponse(HttpStatusCode.BadRequest, $"Cannot load new package {packFn} for replacing via PUT. Aborting."); @@ -1384,14 +1399,14 @@ public void EvalGetAasxByAssetId(IHttpContext context) { string path = context.Request.PathInfo; string[] split = path.Split('/'); - string node = split[2]; - string assetId = split[3].ToUpper(); + string node = split[ 2 ]; + string assetId = split[ 3 ].ToUpper(); for (int envi = 0; envi < Packages.Length; envi++) { - if (this.Packages[envi] != null) + if (this.Packages[ envi ] != null) { - foreach (var aas in this.Packages[envi].AasEnv.AssetAdministrationShells) + foreach (var aas in this.Packages[ envi ].AasEnv.AssetAdministrationShells) { if (aas.AssetInformation != null) { @@ -1419,9 +1434,12 @@ public void EvalGetAasxByAssetId(IHttpContext context) System.IO.Stream s = null; try { - s = Program.env[envi].GetLocalThumbnailStream(); + s = Program.env[ envi ].GetLocalThumbnailStream(); + } + catch + { } - catch { } + if (s != null) { using (var m = new System.IO.MemoryStream()) @@ -1429,29 +1447,31 @@ public void EvalGetAasxByAssetId(IHttpContext context) s.CopyTo(m); detailsImage = System.Convert.ToBase64String(m.ToArray()); } + if (detailsImage != "") { text += "
" + - "Your product image:" + - "
\"Details
"; + "Your product image:" + + "
\"Details
"; } } } + text += "
"; // var link = "http://" + Program.hostPort + "/server/getaasxbyassetid/" + assetId; var link = Program.externalRest + "/server/getaasxbyassetid/" + assetId; text += "Please open AAS in AASX Package Explorer by: File / Other Connect Options / Connect via REST:
" + - "" + - link + "" + "

"; + "" + + link + "" + "

"; text += "Please use Postman to get raw data:
GET " + - "" + - link + "" + "
" + - "and set Headers / Accept application/aas" + "

"; + "" + + link + "" + "
" + + "and set Headers / Accept application/aas" + "

"; context.Response.ContentType = ContentType.HTML; context.Response.ContentEncoding = System.Text.Encoding.UTF8; @@ -1467,6 +1487,7 @@ public void EvalGetAasxByAssetId(IHttpContext context) } } } + context.Response.SendResponse(HttpStatusCode.NotFound, $"No AAS with assetId '{assetId}' found."); } @@ -1489,7 +1510,7 @@ public void EvalDeleteAasAndAsset(IHttpContext context, string aasid, bool delet } // datastructure update - if (this.Packages[0] == null || this.Packages[0].AasEnv == null || this.Packages[0].AasEnv.AssetAdministrationShells == null) + if (this.Packages[ 0 ] == null || this.Packages[ 0 ].AasEnv == null || this.Packages[ 0 ].AasEnv.AssetAdministrationShells == null) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -1509,11 +1530,11 @@ public void EvalDeleteAasAndAsset(IHttpContext context, string aasid, bool delet // delete context.Server.Logger.Debug($"Deleting AdministrationShell with IdShort {findAasReturn.aas.IdShort ?? "--"} and id {findAasReturn.aas.Id?.ToString() ?? "--"}"); - this.Packages[findAasReturn.iPackage].AasEnv.AssetAdministrationShells.Remove(findAasReturn.aas); + this.Packages[ findAasReturn.iPackage ].AasEnv.AssetAdministrationShells.Remove(findAasReturn.aas); - if (this.Packages[findAasReturn.iPackage].AasEnv.AssetAdministrationShells.Count == 0) + if (this.Packages[ findAasReturn.iPackage ].AasEnv.AssetAdministrationShells.Count == 0) { - this.Packages[findAasReturn.iPackage] = null; + this.Packages[ findAasReturn.iPackage ] = null; } else { @@ -1565,7 +1586,7 @@ public void EvalGetAssetLinks(IHttpContext context, string assetid) var handle = IdRefHandleStore.ResolveSpecific(assetid, specialHandles); if (handle != null && handle.identification != null) { - foreach (var aas in this.Packages[0].AasEnv.AssetAdministrationShells) + foreach (var aas in this.Packages[ 0 ].AasEnv.AssetAdministrationShells) if (aas.AssetInformation != null && (aas.AssetInformation.GlobalAssetId.Equals(handle.identification))) { dynamic o = new ExpandoObject(); @@ -1576,7 +1597,7 @@ public void EvalGetAssetLinks(IHttpContext context, string assetid) } else { - foreach (var aas in this.Packages[0].AasEnv.AssetAdministrationShells) + foreach (var aas in this.Packages[ 0 ].AasEnv.AssetAdministrationShells) if (aas.IdShort != null && aas.IdShort.Trim() != "" && aas.IdShort.Trim().ToLower() == assetid.Trim().ToLower()) { dynamic o = new ExpandoObject(); @@ -1734,6 +1755,7 @@ public void EvalPutAssetToAas(IHttpContext context, string aasid) object existingAsset = null; SendTextResponse(context, "OK" + ((existingAsset != null) ? " (updated)" : " (new)")); } + #endregion #region // List of Submodels @@ -1744,7 +1766,9 @@ public class GetSubmodelsItem public string IdShort = ""; public string kind = ""; - public GetSubmodelsItem() { } + public GetSubmodelsItem() + { + } public GetSubmodelsItem(IIdentifiable id, string IdShort, string kind) { @@ -1793,7 +1817,7 @@ public void EvalGetSubmodels(IHttpContext context, string aasid) // get all submodels foreach (var smref in findAasReturn.aas.Submodels) { - var sm = this.Packages[findAasReturn.iPackage].AasEnv.FindSubmodel(smref); + var sm = this.Packages[ findAasReturn.iPackage ].AasEnv.FindSubmodel(smref); if (sm != null) { //res.Add(new GetSubmodelsItem(sm, sm.kind.kind)); @@ -1807,6 +1831,7 @@ public void EvalGetSubmodels(IHttpContext context, string aasid) } static long countPut = 0; + public void EvalPutSubmodel(IHttpContext context, string aasid) { dynamic res = new ExpandoObject(); @@ -1850,7 +1875,7 @@ public void EvalPutSubmodel(IHttpContext context, string aasid) { JsonSerializer serializer = new JsonSerializer(); serializer.Converters.Add(new AdminShellConverters.JsonAasxConverter("modelType", "name")); - submodel = (Submodel)serializer.Deserialize(reader, typeof(Submodel)); + submodel = (Submodel) serializer.Deserialize(reader, typeof(Submodel)); } } catch (Exception ex) @@ -1869,7 +1894,8 @@ public void EvalPutSubmodel(IHttpContext context, string aasid) } // datastructure update - if (this.Packages[findAasReturn.iPackage] == null || this.Packages[findAasReturn.iPackage].AasEnv == null /*|| this.Packages[findAasReturn.iPackage].AasEnv.Assets == null*/) + if (this.Packages[ findAasReturn.iPackage ] == null || + this.Packages[ findAasReturn.iPackage ].AasEnv == null /*|| this.Packages[findAasReturn.iPackage].AasEnv.Assets == null*/) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -1877,21 +1903,21 @@ public void EvalPutSubmodel(IHttpContext context, string aasid) // add Submodel context.Server.Logger.Debug($"Adding Submodel with IdShort {submodel.IdShort ?? "--"} and id {submodel.Id?.ToString() ?? "--"}"); - var existingSm = this.Packages[findAasReturn.iPackage].AasEnv.FindSubmodelById(submodel.Id); + var existingSm = this.Packages[ findAasReturn.iPackage ].AasEnv.FindSubmodelById(submodel.Id); if (existingSm != null) { - int indexOfExistingSm = this.Packages[findAasReturn.iPackage].AasEnv.Submodels.IndexOf(existingSm); - this.Packages[findAasReturn.iPackage].AasEnv.Submodels.RemoveAt(indexOfExistingSm); - this.Packages[findAasReturn.iPackage].AasEnv.Submodels.Insert(indexOfExistingSm, submodel); + int indexOfExistingSm = this.Packages[ findAasReturn.iPackage ].AasEnv.Submodels.IndexOf(existingSm); + this.Packages[ findAasReturn.iPackage ].AasEnv.Submodels.RemoveAt(indexOfExistingSm); + this.Packages[ findAasReturn.iPackage ].AasEnv.Submodels.Insert(indexOfExistingSm, submodel); } else { - this.Packages[findAasReturn.iPackage].AasEnv.Submodels.Add(submodel); + this.Packages[ findAasReturn.iPackage ].AasEnv.Submodels.Add(submodel); } // add SubmodelRef to AAS var key = new Key(KeyTypes.Submodel, submodel.Id); - var KeyList = new List() { key }; + var KeyList = new List() {key}; Reference newsmr = new Reference(AasCore.Aas3_0.ReferenceTypes.ModelReference, KeyList); //var newsmr = SubmodelRef.CreateNew("Submodel", submodel.Id); var existsmr = findAasReturn.aas.HasSubmodelReference(newsmr); @@ -1946,7 +1972,8 @@ public void EvalDeleteSubmodel(IHttpContext context, string aasid, string smid) var smref = this.FindSubmodelRefWithinAas(findAasReturn, smid, context.Request.QueryString, context.Request.RawUrl); if (smref != null) { - context.Server.Logger.Debug($"Removing SubmodelRef {smid} from AAS with IdShort {findAasReturn.aas.IdShort ?? "--"} and id {findAasReturn.aas.Id?.ToString() ?? "--"}"); + context.Server.Logger.Debug( + $"Removing SubmodelRef {smid} from AAS with IdShort {findAasReturn.aas.IdShort ?? "--"} and id {findAasReturn.aas.Id?.ToString() ?? "--"}"); findAasReturn.aas.Submodels.Remove(smref); } @@ -1955,7 +1982,7 @@ public void EvalDeleteSubmodel(IHttpContext context, string aasid, string smid) if (sm != null) { context.Server.Logger.Debug($"Removing Submodel {smid} from data structures."); - this.Packages[findAasReturn.iPackage].AasEnv.Submodels.Remove(sm); + this.Packages[ findAasReturn.iPackage ].AasEnv.Submodels.Remove(sm); } // simple OK @@ -1971,6 +1998,7 @@ public void EvalDeleteSubmodel(IHttpContext context, string aasid, string smid) #endregion #region // Submodel Complete + static long countGet = 0; public void EvalGetSubmodelContents(IHttpContext context, string aasid, string smid, bool deep = false, bool complete = false) @@ -2035,7 +2063,7 @@ public void EvalGetSubmodelContentsAsTable(IHttpContext context, string aasid, s } // AAS ENV - if (this.Packages[0] == null || this.Packages[0].AasEnv == null) + if (this.Packages[ 0 ] == null || this.Packages[ 0 ].AasEnv == null) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -2067,7 +2095,8 @@ public void EvalGetSubmodelContentsAsTable(IHttpContext context, string aasid, s //row.typeName = sme.GetElementName(); row.typeName = sme.GetType().ToString(); if (sme.SemanticId == null || sme.SemanticId.Keys == null /*|| sme.semanticId.Keys.Count == 0*/) - { } + { + } else if (sme.SemanticId.Keys.Count > 1) { row.semId = "(complex)"; @@ -2082,7 +2111,7 @@ public void EvalGetSubmodelContentsAsTable(IHttpContext context, string aasid, s // try find a concept description if (sme.SemanticId != null) { - var cd = this.Packages[0].AasEnv.FindConceptDescriptionByReference(sme.SemanticId); + var cd = this.Packages[ 0 ].AasEnv.FindConceptDescriptionByReference(sme.SemanticId); if (cd != null) { // TODO (jtikekar, 2023-09-04): Temporarily commented @@ -2134,7 +2163,6 @@ public void EvalGetSubmodelContentsAsTable(IHttpContext context, string aasid, s // recurse return true; - }); // return as JSON @@ -2251,6 +2279,7 @@ private string EvalGetSubmodelElementsProperty_EvalValue(Property smep) dblval += Math.Sin((0.001 * DateTime.UtcNow.Millisecond) * 6.28); strval = dblval.ToString(CultureInfo.InvariantCulture); } + return strval; } @@ -2271,7 +2300,7 @@ private List EvalGetSubmodelElementsProperty_EvalValues( var path = new List(); path.Add("" + smep?.IdShort); for (int i = pars.Count - 1; i >= 0; i--) - path.Insert(0, "" + pars[i].IdShort); + path.Insert(0, "" + pars[ i ].IdShort); dynamic tuple = new ExpandoObject(); tuple.path = path; @@ -2338,7 +2367,7 @@ public void EvalGetSubmodelAllElementsProperty(IHttpContext context, string aasi else { context.Response.SendResponse(HttpStatusCode.NotFound, $"No matching Property element(s) " + - $"in Submodel found."); + $"in Submodel found."); return; } } @@ -2385,7 +2414,7 @@ public void EvalGetSubmodelElementsFile(IHttpContext context, string aasid, stri } // access - var packageStream = this.Packages[0].GetLocalStreamFromPackage(smef.Value); + var packageStream = this.Packages[ 0 ].GetLocalStreamFromPackage(smef.Value); if (packageStream == null) { context.Response.SendResponse(HttpStatusCode.NotFound, $"No file contents available in package."); @@ -2460,7 +2489,7 @@ public void EvalPutSubmodelElementContents(IHttpContext context, string aasid, s // Check query parameter bool first = false; var queryString = context.Request.QueryString; - string f = queryString["first"]; + string f = queryString[ "first" ]; if (f != null && f != "") { first = true; @@ -2541,6 +2570,7 @@ public void EvalPutSubmodelElementContents(IHttpContext context, string aasid, s context.Server.Logger.Debug($"Adding new SubmodelElement {sme.IdShort} to SubmodelCollection."); parentsmc.Add(sme); } + sme.SetAllParentsAndTimestamps(parentsmc, timeStamp, sme.TimeStampCreate); sme.SetTimeStamp(timeStamp); } @@ -2599,7 +2629,7 @@ public void EvalDeleteSubmodelElementContents(IHttpContext context, string aasid { context.Server.Logger.Debug($"Deleting specified SubmodelElement {elinfo} from Submodel {smid}."); AasxRestServerLibrary.AasxRestServer.TestResource.eventMessage.add( - fse.submodelElement, "Remove", sm, (ulong)DateTime.UtcNow.Ticks); + fse.submodelElement, "Remove", sm, (ulong) DateTime.UtcNow.Ticks); sm.SubmodelElements.Remove(fse.submodelElement); deleted = true; } @@ -2683,7 +2713,7 @@ public void EvalInvokeSubmodelElementOperation(IHttpContext context, string aasi { numGivenInputArgs = input.Count; for (int i = 0; i < numGivenInputArgs; i++) - inputArguments[i] = input[i]; + inputArguments[ i ] = input[ i ]; } } catch (Exception ex) @@ -2704,7 +2734,7 @@ public void EvalInvokeSubmodelElementOperation(IHttpContext context, string aasi if (smep.FindQualifierOfType("DEMO") != null) { for (int i = 0; i < Math.Min(numExpectedInputArgs, numExpectedOutputArgs); i++) - outputArguments[i] = "CALC on " + inputArguments[i]; + outputArguments[ i ] = "CALC on " + inputArguments[ i ]; } // return as little dynamic object @@ -2744,7 +2774,8 @@ public void EvalGetAllCds(IHttpContext context, string aasid) // create a new, filtered AasEnv // (this is expensive, but delivers us with a list of CDs which are in relation to the respective AAS) var copyenv = new AasCore.Aas3_0.Environment(); - copyenv = copyenv.CreateFromExistingEnvironment(this.Packages[findAasReturn.iPackage].AasEnv, filterForAas: new List(new AssetAdministrationShell[] { (AssetAdministrationShell)findAasReturn.aas })); + copyenv = copyenv.CreateFromExistingEnvironment(this.Packages[ findAasReturn.iPackage ].AasEnv, + filterForAas: new List(new AssetAdministrationShell[] {(AssetAdministrationShell) findAasReturn.aas})); // get all CDs and describe them foreach (var cd in copyenv.ConceptDescriptions) @@ -2828,9 +2859,10 @@ public void EvalDeleteSpecificCd(IHttpContext context, string aasid, string cdid // delete ?! var deleted = false; - if (this.Packages[findAasReturn.iPackage] != null && this.Packages[findAasReturn.iPackage].AasEnv != null && this.Packages[findAasReturn.iPackage].AasEnv.ConceptDescriptions.Contains(cd)) + if (this.Packages[ findAasReturn.iPackage ] != null && this.Packages[ findAasReturn.iPackage ].AasEnv != null && + this.Packages[ findAasReturn.iPackage ].AasEnv.ConceptDescriptions.Contains(cd)) { - this.Packages[findAasReturn.iPackage].AasEnv.ConceptDescriptions.Remove(cd); + this.Packages[ findAasReturn.iPackage ].AasEnv.ConceptDescriptions.Remove(cd); deleted = true; } @@ -2906,6 +2938,7 @@ public void EvalPostHandlesIdentification(IHttpContext context) context.Response.SendResponse(HttpStatusCode.BadRequest, $"Cannot deserialize payload: {ex.Message}."); return; } + if (ids == null || ids.Count < 1) { context.Response.SendResponse(HttpStatusCode.BadRequest, $"No Identification entities in payload."); @@ -2956,8 +2989,9 @@ public void EvalGetServerProfile(IHttpContext context) // get the list dynamic res = new ExpandoObject(); - var capabilities = new List(new ulong[]{ - 80,81,82,10,11,12,13,15,16,20,21,30,31,40,41,42,43,50,51,52,53,54,55,56,57,58,59,60,61,70,71,72,73 + var capabilities = new List(new ulong[] + { + 80, 81, 82, 10, 11, 12, 13, 15, 16, 20, 21, 30, 31, 40, 41, 42, 43, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 70, 71, 72, 73 }); res.apiversion = 1; res.capabilities = capabilities; @@ -2990,13 +3024,13 @@ public void EvalGetAuthenticateGuest(IHttpContext context) // string with real random numbers Byte[] barray = new byte[100]; rngCsp.GetBytes(barray); - sessionRandom[sessionCount] = Convert.ToBase64String(barray); + sessionRandom[ sessionCount ] = Convert.ToBase64String(barray); dynamic res = new ExpandoObject(); var payload = new Dictionary() { - { "sessionID", sessionCount }, - { "sessionRandom", sessionRandom[sessionCount] } + {"sessionID", sessionCount}, + {"sessionRandom", sessionRandom[ sessionCount ]} }; System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); @@ -3007,8 +3041,8 @@ public void EvalGetAuthenticateGuest(IHttpContext context) withAuthentification = true; - sessionUserType[sessionCount] = 'G'; - sessionUserName[sessionCount] = "guest"; + sessionUserType[ sessionCount ] = 'G'; + sessionUserName[ sessionCount ] = "guest"; sessionCount++; if (sessionCount >= 100) { @@ -3052,7 +3086,7 @@ public void EvalPostAuthenticateUser(IHttpContext context) for (int i = 0; i < userCount; i++) { - if (user == securityUserName[i] && password == securityUserPassword[i]) + if (user == securityUserName[ i ] && password == securityUserPassword[ i ]) { userFound = true; break; @@ -3070,12 +3104,12 @@ public void EvalPostAuthenticateUser(IHttpContext context) // string with real random numbers Byte[] barray = new byte[100]; rngCsp.GetBytes(barray); - sessionRandom[sessionCount] = Convert.ToBase64String(barray); + sessionRandom[ sessionCount ] = Convert.ToBase64String(barray); var payload = new Dictionary() { - { "sessionID", sessionCount }, - { "sessionRandom", sessionRandom[sessionCount] } + {"sessionID", sessionCount}, + {"sessionRandom", sessionRandom[ sessionCount ]} }; System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); @@ -3084,8 +3118,8 @@ public void EvalPostAuthenticateUser(IHttpContext context) Console.WriteLine("SessionID: " + sessionCount); Console.WriteLine("sessionRandom: " + token); - sessionUserType[sessionCount] = 'U'; - sessionUserName[sessionCount] = user; + sessionUserType[ sessionCount ] = 'U'; + sessionUserName[ sessionCount ] = user; sessionCount++; if (sessionCount >= 100) { @@ -3106,10 +3140,10 @@ public void EvalPostAuthenticateCert1(IHttpContext context) Console.WriteLine(); Console.WriteLine("Security 2 Server: /AuthenticateCert1"); // POST token with user - sessionUserType[sessionCount] = ' '; - sessionUserName[sessionCount] = ""; - sessionRandom[sessionCount] = ""; - sessionChallenge[sessionCount] = ""; + sessionUserType[ sessionCount ] = ' '; + sessionUserName[ sessionCount ] = ""; + sessionRandom[ sessionCount ] = ""; + sessionChallenge[ sessionCount ] = ""; bool error = false; @@ -3125,7 +3159,7 @@ public void EvalPostAuthenticateCert1(IHttpContext context) token = parsed.SelectToken("token").Value(); var headers = Jose.JWT.Headers(token); - string x5c = headers["x5c"].ToString(); + string x5c = headers[ "x5c" ].ToString(); if (x5c != "") { @@ -3141,7 +3175,7 @@ public void EvalPostAuthenticateCert1(IHttpContext context) string[] x5c64 = JsonConvert.DeserializeObject(x5c); X509Certificate2Collection xcc = new X509Certificate2Collection(); - Byte[] certFileBytes = Convert.FromBase64String(x5c64[0]); + Byte[] certFileBytes = Convert.FromBase64String(x5c64[ 0 ]); string fileCert = "./temp/" + user + ".cer"; System.IO.File.WriteAllBytes(fileCert, certFileBytes); Console.WriteLine("Security 2.1b Server: " + fileCert + " received"); @@ -3159,7 +3193,7 @@ public void EvalPostAuthenticateCert1(IHttpContext context) for (int i = 1; i < x5c64.Length; i++) { - var cert = new X509Certificate2(Convert.FromBase64String(x5c64[i])); + var cert = new X509Certificate2(Convert.FromBase64String(x5c64[ i ])); Console.WriteLine("Security 2.1c Certificate in Chain: " + cert.Subject); if (cert.Subject != cert.Issuer) { @@ -3247,7 +3281,7 @@ public void EvalPostAuthenticateCert1(IHttpContext context) rngCsp.GetBytes(barray); Console.WriteLine("Security 2.3 Server: Create session unique challenge by real random"); - sessionChallenge[sessionCount] = Convert.ToBase64String(barray); + sessionChallenge[ sessionCount ] = Convert.ToBase64String(barray); } if (error) @@ -3258,15 +3292,15 @@ public void EvalPostAuthenticateCert1(IHttpContext context) } Console.WriteLine("sessionID: " + sessionCount); - Console.WriteLine("session challenge: " + sessionChallenge[sessionCount]); + Console.WriteLine("session challenge: " + sessionChallenge[ sessionCount ]); - sessionUserType[sessionCount] = 'T'; - sessionUserName[sessionCount] = user; - sessionUserPulicKey[sessionCount] = publicKey; + sessionUserType[ sessionCount ] = 'T'; + sessionUserName[ sessionCount ] = user; + sessionUserPulicKey[ sessionCount ] = publicKey; withAuthentification = true; - res.challenge = sessionChallenge[sessionCount]; + res.challenge = sessionChallenge[ sessionCount ]; context.Response.StatusCode = HttpStatusCode.Ok; SendJsonResponse(context, res); @@ -3277,7 +3311,7 @@ public void EvalPostAuthenticateCert2(IHttpContext context) Console.WriteLine(); Console.WriteLine("Security 3 Server: /AuthenticateCert2"); // POST token with user - sessionRandom[sessionCount] = ""; + sessionRandom[ sessionCount ] = ""; bool error = false; @@ -3300,7 +3334,7 @@ public void EvalPostAuthenticateCert2(IHttpContext context) error = true; } - if (challenge != sessionChallenge[sessionCount] || sessionChallenge[sessionCount] == null || sessionChallenge[sessionCount] == "") + if (challenge != sessionChallenge[ sessionCount ] || sessionChallenge[ sessionCount ] == null || sessionChallenge[ sessionCount ] == "") { error = true; } @@ -3309,7 +3343,7 @@ public void EvalPostAuthenticateCert2(IHttpContext context) { try { - publicKey = sessionUserPulicKey[sessionCount]; + publicKey = sessionUserPulicKey[ sessionCount ]; Jose.JWT.Decode(token, publicKey, JwsAlgorithm.RS256); // signed by user key? Console.WriteLine("Security 3.1 Server: Validate challenge signature with publicKey"); @@ -3328,17 +3362,17 @@ public void EvalPostAuthenticateCert2(IHttpContext context) Byte[] barray = new byte[100]; rngCsp.GetBytes(barray); Console.WriteLine("Security 3.2 Server: Create session unique bearerToken signed by real random"); - sessionRandom[sessionCount] = Convert.ToBase64String(barray); + sessionRandom[ sessionCount ] = Convert.ToBase64String(barray); var payload = new Dictionary() { - { "sessionID", sessionCount }, + {"sessionID", sessionCount}, }; try { var enc = new System.Text.ASCIIEncoding(); - token = Jose.JWT.Encode(payload, enc.GetBytes(sessionRandom[sessionCount]), JwsAlgorithm.HS256); + token = Jose.JWT.Encode(payload, enc.GetBytes(sessionRandom[ sessionCount ]), JwsAlgorithm.HS256); Console.WriteLine("Security 3.3 Server: Sign sessionID by server sessionRandom"); } catch @@ -3355,7 +3389,7 @@ public void EvalPostAuthenticateCert2(IHttpContext context) } Console.WriteLine("sessionID: " + sessionCount); - Console.WriteLine("session random: " + sessionRandom[sessionCount]); + Console.WriteLine("session random: " + sessionRandom[ sessionCount ]); Console.WriteLine("session bearerToken: " + token); sessionCount++; @@ -3382,6 +3416,7 @@ public static bool checkAccessLevel(string currentRole, string operation, string return checkAccessLevelWithError(out error, currentRole, operation, neededRights, out withAllow, out getPolicy, objPath, aasOrSubmodel, objectAasOrSubmodel); } + public static bool checkAccessLevelWithAllow(string currentRole, string operation, string neededRights, out bool withAllow, string objPath = "", string aasOrSubmodel = null, object objectAasOrSubmodel = null, string policy = null) @@ -3392,6 +3427,7 @@ public static bool checkAccessLevelWithAllow(string currentRole, string operatio return checkAccessLevelWithError(out error, currentRole, operation, neededRights, out withAllow, out getPolicy, objPath, aasOrSubmodel, objectAasOrSubmodel, policy); } + public static bool checkAccessLevelWithError(out string error, string currentRole, string operation, string neededRights, out bool withAllow, out string getPolicy, string objPath = "", string aasOrSubmodel = null, object objectAasOrSubmodel = null, string policy = null) @@ -3399,7 +3435,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol error = ""; getPolicy = null; withAllow = false; - + if (Program.secretStringAPI != null) { /* @@ -3416,29 +3452,29 @@ public static bool checkAccessLevelWithError(out string error, string currentRol currentRole = "isNotAuthenticated"; Console.WriteLine("checkAccessLevel: " + - " currentRole = " + currentRole + - " operation = " + operation + - " neededRights = " + neededRights + - " objPath = " + objPath - ); + " currentRole = " + currentRole + + " operation = " + operation + + " neededRights = " + neededRights + + " objPath = " + objPath + ); if (objPath == "") { int iRole = 0; - while (securityRole != null && iRole < securityRole.Count && securityRole[iRole].name != null) + while (securityRole != null && iRole < securityRole.Count && securityRole[ iRole ].name != null) { - if (aasOrSubmodel == "aas" && securityRole[iRole].objType == "aas") - /* (aasOrSubmodel == "submodel" && securityRole[iRole].objType == "sm")) */ + if (aasOrSubmodel == "aas" && securityRole[ iRole ].objType == "aas") + /* (aasOrSubmodel == "submodel" && securityRole[iRole].objType == "sm")) */ { - if (objectAasOrSubmodel != null && securityRole[iRole].objReference == objectAasOrSubmodel && - securityRole[iRole].permission == neededRights) + if (objectAasOrSubmodel != null && securityRole[ iRole ].objReference == objectAasOrSubmodel && + securityRole[ iRole ].permission == neededRights) { - if ((securityRole[iRole].condition == "" && securityRole[iRole].name == currentRole) || - (securityRole[iRole].condition == "not" && securityRole[iRole].name != currentRole)) + if ((securityRole[ iRole ].condition == "" && securityRole[ iRole ].name == currentRole) || + (securityRole[ iRole ].condition == "not" && securityRole[ iRole ].name != currentRole)) { - if (securityRole[iRole].kind == "allow") + if (securityRole[ iRole ].kind == "allow") return true; - if (securityRole[iRole].kind == "deny") + if (securityRole[ iRole ].kind == "deny") { error = "DENY AAS " + (objectAasOrSubmodel as AssetAdministrationShell).Id; return false; @@ -3446,20 +3482,23 @@ public static bool checkAccessLevelWithError(out string error, string currentRol } } } - if (securityRole[iRole].name == currentRole && securityRole[iRole].objType == "api" && - securityRole[iRole].permission == neededRights) + + if (securityRole[ iRole ].name == currentRole && securityRole[ iRole ].objType == "api" && + securityRole[ iRole ].permission == neededRights) { - if (securityRole[iRole].apiOperation == "*" || securityRole[iRole].apiOperation == operation) + if (securityRole[ iRole ].apiOperation == "*" || securityRole[ iRole ].apiOperation == operation) { - if (securityRole[iRole].permission == neededRights) + if (securityRole[ iRole ].permission == neededRights) { - return checkPolicy(out error, securityRole[iRole], out getPolicy); + return checkPolicy(out error, securityRole[ iRole ], out getPolicy); } } } + iRole++; } } + if (objPath != "" && (operation == "/submodels" || operation == "/submodelelements")) { // next object with rule must have allow @@ -3478,7 +3517,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol { if (role.semanticId == "*" || (s.SemanticId != null && s.SemanticId.Keys != null && s.SemanticId.Keys.Count != 0)) { - if (role.semanticId == "*" || (role.semanticId.ToLower() == s.SemanticId.Keys[0].Value.ToLower())) + if (role.semanticId == "*" || (role.semanticId.ToLower() == s.SemanticId.Keys[ 0 ].Value.ToLower())) { if (role.kind == "allow") { @@ -3489,6 +3528,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol deepestAllowRole = role; } } + if (role.kind == "deny") { if (deepestDeny == "") @@ -3497,6 +3537,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol } } } + if (objectAasOrSubmodel is string s2) { if (s2 != null && s2 != "") @@ -3512,6 +3553,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol deepestAllowRole = role; } } + if (role.kind == "deny") { if (deepestDeny == "") @@ -3521,6 +3563,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol } } } + if ((role.objType == "sm" || role.objType == "submodelElement") && role.submodel == objectAasOrSubmodel && role.permission == neededRights) { @@ -3531,6 +3574,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol if (role.objPath == objPath.Substring(0, role.objPath.Length)) deepestDeny = role.objPath; } + if (role.objPath.Length >= objPath.Length) // deny in tree below { if (objPath == role.objPath.Substring(0, objPath.Length)) @@ -3540,6 +3584,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol } } } + if (role.kind == "allow") { if (objPath.Length >= role.objPath.Length) // allow in tree above @@ -3554,16 +3599,19 @@ public static bool checkAccessLevelWithError(out string error, string currentRol } } } + if (deepestAllow == "") { error = "ALLOW not defined"; return false; } + if (deepestDeny.Length > deepestAllow.Length) { error = "DENY " + deepestDeny; return false; } + return checkPolicy(out error, deepestAllowRole, out getPolicy, policy); } @@ -3574,7 +3622,7 @@ public static bool checkAccessLevelWithError(out string error, string currentRol public static bool checkPolicy(out string error, securityRoleClass sr, out string getPolicy, string policy = null) { error = ""; - getPolicy= null; + getPolicy = null; Property pPolicy = null; AasCore.Aas3_0.File fPolicy = null; @@ -3610,6 +3658,7 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin break; } } + if (maxCount == null || duration == null || actualCount == null || actualTime == null) return false; int d = 0; @@ -3617,6 +3666,7 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin { return false; } + DateTime dt = new DateTime(); if (actualTime.Value != null && actualTime.Value != "") { @@ -3629,29 +3679,36 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin actualTime.Value = null; } } - catch { } + catch + { + } } + if (actualTime.Value == null || actualTime.Value == "") { actualTime.Value = DateTime.UtcNow.ToString(); actualCount.Value = null; } + if (actualCount.Value == null || actualCount.Value == "") { actualCount.Value = "0"; } + int ac = 0; if (!int.TryParse(actualCount.Value, out ac)) { Program.signalNewData(0); return false; } + int mc = 0; if (!int.TryParse(maxCount.Value, out mc)) { Program.signalNewData(0); return false; } + ac++; actualCount.Value = ac.ToString(); if (ac <= mc) @@ -3660,6 +3717,7 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin return true; } } + break; case "policy": pPolicy = sme as Property; @@ -3682,12 +3740,12 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin { try { - using (System.IO.Stream s = Program.env[sr.usageEnvIndex].GetLocalStreamFromPackage(fPolicy.Value)) + using (System.IO.Stream s = Program.env[ sr.usageEnvIndex ].GetLocalStreamFromPackage(fPolicy.Value)) using (SHA256 mySHA256 = SHA256.Create()) { if (s != null) { - s.Position= 0; + s.Position = 0; byte[] hashValue = mySHA256.ComputeHash(s); getPolicy = Convert.ToHexString(hashValue); Console.WriteLine("hash: " + getPolicy); @@ -3695,7 +3753,9 @@ public static bool checkPolicy(out string error, securityRoleClass sr, out strin } } } - catch { } + catch + { + } } if (policy == null || policy.Contains(getPolicy)) @@ -3723,10 +3783,11 @@ public bool checkAccessRights(IHttpContext context, string currentRole, string o if (currentRole == "CREATE") return true; } + // else { if (checkAccessLevel(currentRole, operation, neededRights, - objPath, aasOrSubmodel, objectAasOrSubmodel)) + objPath, aasOrSubmodel, objectAasOrSubmodel)) return true; if (currentRole == null) @@ -3761,15 +3822,15 @@ public static string SecurityCheck(IHttpContext context, ref int index) static string checkUserPW(string userPW64) { var credentialBytes = Convert.FromBase64String(userPW64); - var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); - string username = credentials[0]; - string password = credentials[1]; + var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] {':'}, 2); + string username = credentials[ 0 ]; + string password = credentials[ 1 ]; int userCount = securityUserName.Count; for (int i = 0; i < userCount; i++) { - if (username == securityUserName[i] && password == securityUserPassword[i]) + if (username == securityUserName[ i ] && password == securityUserPassword[ i ]) { return (username); } @@ -3777,6 +3838,7 @@ static string checkUserPW(string userPW64) return null; } + public static string SecurityCheck(NameValueCollection queryString, NameValueCollection headers, ref int index) { string policy = ""; @@ -3793,6 +3855,7 @@ class userCert static List certList = new List(); public static object lockCertList = new object(); + public static string SecurityCheckWithPolicy(NameValueCollection queryString, NameValueCollection headers, ref int index, out string policy, out string policyRequestedResource) { @@ -3821,7 +3884,7 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na // check for secret - string s = queryString["s"]; + string s = queryString[ "s" ]; if (s != null && s != "") { if (Program.secretStringAPI != null) @@ -3841,27 +3904,28 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na // string headers = request.Headers.ToString(); // Check bearer token - token = headers["Authorization"]; + token = headers[ "Authorization" ]; if (token != null) { - split = token.Split(new Char[] { ' ', '\t' }); - if (split[0] != null) + split = token.Split(new Char[] {' ', '\t'}); + if (split[ 0 ] != null) { - if (split[0].ToLower() == "bearer") + if (split[ 0 ].ToLower() == "bearer") { - Console.WriteLine("Received bearer token = " + split[1]); - bearerToken = split[1]; + Console.WriteLine("Received bearer token = " + split[ 1 ]); + bearerToken = split[ 1 ]; } - if (bearerToken == null && split[0].ToLower() == "basic") + + if (bearerToken == null && split[ 0 ].ToLower() == "basic") { try { if (Program.secretStringAPI != null) { - var credentialBytes = Convert.FromBase64String(split[1]); - var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); - string u = credentials[0]; - string p = credentials[1]; + var credentialBytes = Convert.FromBase64String(split[ 1 ]); + var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] {':'}, 2); + string u = credentials[ 0 ]; + string p = credentials[ 1 ]; Console.WriteLine("Received username+password http header = " + u + " : " + p); if (u == "secret") @@ -3876,14 +3940,16 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na } } - string username = checkUserPW(split[1]); + string username = checkUserPW(split[ 1 ]); if (username != null) { user = username; Console.WriteLine("Received username+password http header = " + user); } } - catch { } + catch + { + } } } } @@ -3897,7 +3963,7 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na bearerToken = split[1]; } */ - bearerToken = queryString["bearer"]; + bearerToken = queryString[ "bearer" ]; } if (bearerToken == null) @@ -3906,23 +3972,25 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na } // Check email token - token = headers["Email"]; + token = headers[ "Email" ]; if (token != null) { Console.WriteLine("Received Email token = " + token); user = token; error = false; } + // Check email query string - token = queryString["Email"]; + token = queryString[ "Email" ]; if (token != null) { Console.WriteLine("Received Email query string = " + token); user = token; error = false; } + // Username+password query string - token = queryString["_up"]; + token = queryString[ "_up" ]; if (token != null) { try @@ -3934,7 +4002,9 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na Console.WriteLine("Received username+password query string = " + user); } } - catch { } + catch + { + } } if (!error) @@ -3954,7 +4024,10 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { email = parsed2.SelectToken("email").Value(); } - catch { } + catch + { + } + try { serverName = parsed2.SelectToken("serverName").Value(); @@ -3963,16 +4036,22 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { // serverName = "keycloak"; } + try { policy = parsed2.SelectToken("policy").Value(); } - catch { } + catch + { + } + try { policyRequestedResource = parsed2.SelectToken("policyRequestedResource").Value(); } - catch { } + catch + { + } if (email != "") { @@ -3985,7 +4064,9 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na user = parsed2.SelectToken("userName").Value(); user = user.ToLower(); } - catch { } + catch + { + } if (serverName != "") // token from Auth Server { @@ -4014,7 +4095,9 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { certificate = parsed2.SelectToken("certificate").Value(); } - catch { } + catch + { + } if (certificate != "") { @@ -4025,14 +4108,15 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na int i = 0; for (i = 0; i < certList.Count; i++) { - if (certList[i].userName == user) + if (certList[ i ].userName == user) { - if (certList[i].certificate != null) - certList[i].certificate.Dispose(); - certList[i].certificate = x509; + if (certList[ i ].certificate != null) + certList[ i ].certificate.Dispose(); + certList[ i ].certificate = x509; break; } } + if (i == certList.Count) { var cl = new userCert(); @@ -4051,9 +4135,9 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na int i = 0; for (i = 0; i < certList.Count; i++) { - if (certList[i].userName == user) + if (certList[ i ].userName == user) { - x509 = certList[i].certificate; + x509 = certList[ i ].certificate; break; } } @@ -4067,6 +4151,7 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { x509 = null; } + if (x509 == null) { Console.WriteLine("Invalid client token!"); @@ -4091,31 +4176,33 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { for (int i = 0; i < rightsCount; i++) { - if (securityRights[i].name.Contains("@")) // email address + if (securityRights[ i ].name.Contains("@")) // email address { - if (user == securityRights[i].name) + if (user == securityRights[ i ].name) { // accessrights = securityRightsValue[i]; - accessrights = securityRights[i].role; + accessrights = securityRights[ i ].role; return accessrights; } } } } + for (int i = 0; i < rightsCount; i++) { - if (!securityRights[i].name.Contains("@")) // domain name only or non email + if (!securityRights[ i ].name.Contains("@")) // domain name only or non email { string u = user; if (user.Contains("@")) { string[] splitUser = user.Split('@'); - u = splitUser[1]; // domain only + u = splitUser[ 1 ]; // domain only } - if (u == securityRights[i].name) + + if (u == securityRights[ i ].name) { // accessrights = securityRightsValue[i]; - accessrights = securityRights[i].role; + accessrights = securityRights[ i ].role; return accessrights; } } @@ -4145,7 +4232,7 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { string payload = null; - switch (sessionUserType[id]) + switch (sessionUserType[ id ]) { case 'G': case 'U': @@ -4193,6 +4280,7 @@ public static string SecurityCheckWithPolicy(NameValueCollection queryString, Na { index = id; } + return accessrights; } @@ -4213,9 +4301,9 @@ public void EvalGetListAAS(IHttpContext context, bool withasset = false) for (int i = 0; i < aascount; i++) { - if (AasxServer.Program.env[i] != null) + if (AasxServer.Program.env[ i ] != null) { - var aas = AasxServer.Program.env[i].AasEnv.AssetAdministrationShells[0]; + var aas = AasxServer.Program.env[ i ].AasEnv.AssetAdministrationShells[ 0 ]; string IdShort = aas.IdShort; string aasRights = "NONE"; if (securityRightsAAS != null && securityRightsAAS.Count != 0) @@ -4232,9 +4320,9 @@ public void EvalGetListAAS(IHttpContext context, bool withasset = false) if (addEntry) { string s = i.ToString() + " : " - + IdShort + " : " - + aas.Id + " : " - + AasxServer.Program.envFileName[i]; + + IdShort + " : " + + aas.Id + " : " + + AasxServer.Program.envFileName[ i ]; if (withasset) { //var asset = Program.env[i].AasEnv.FindAsset(aas.assetRef); @@ -4242,6 +4330,7 @@ public void EvalGetListAAS(IHttpContext context, bool withasset = false) s += " : " + asset.GlobalAssetId; s += " : " + asset.AssetKind; } + aaslist.Add(s); } } @@ -4317,7 +4406,7 @@ public void EvalGetAASX(IHttpContext context, int fileIndex) res.confirm = "Authorization = " + accessrights; */ - var aas = Program.env[fileIndex].AasEnv.AssetAdministrationShells[0]; + var aas = Program.env[ fileIndex ].AasEnv.AssetAdministrationShells[ 0 ]; if (!checkAccessRights(context, accessrights, "/aasx", "READ", "", "aas", aas)) { return; @@ -4339,14 +4428,14 @@ public void EvalGetAASX(IHttpContext context, int fileIndex) lock (Program.changeAasxFile) { - string fname = "./temp/" + Path.GetFileName(Program.envFileName[fileIndex]); - Program.env[fileIndex].SaveAs(fname); + string fname = "./temp/" + Path.GetFileName(Program.envFileName[ fileIndex ]); + Program.env[ fileIndex ].SaveAs(fname); // return as FILE FileStream packageStream = System.IO.File.OpenRead(fname); context.Response.StatusCode = HttpStatusCode.Ok; SendStreamResponse(context, packageStream, - Path.GetFileName(AasxServer.Program.envFileName[fileIndex])); + Path.GetFileName(AasxServer.Program.envFileName[ fileIndex ])); packageStream.Close(); // Reload @@ -4404,7 +4493,7 @@ public void EvalGetAASX2(IHttpContext context, int fileIndex) res.confirm = "Authorization = " + accessrights; - Byte[] binaryFile = System.IO.File.ReadAllBytes(AasxServer.Program.envFileName[fileIndex]); + Byte[] binaryFile = System.IO.File.ReadAllBytes(AasxServer.Program.envFileName[ fileIndex ]); string binaryBase64 = Convert.ToBase64String(binaryFile); string payload = "{ \"file\" : \" " + binaryBase64 + " \" }"; @@ -4412,12 +4501,13 @@ public void EvalGetAASX2(IHttpContext context, int fileIndex) System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); string fileToken = Jose.JWT.Encode(payload, enc.GetBytes(secretString), JwsAlgorithm.HS256); - res.fileName = Path.GetFileName(AasxServer.Program.envFileName[fileIndex]); + res.fileName = Path.GetFileName(AasxServer.Program.envFileName[ fileIndex ]); res.fileData = fileToken; context.Response.StatusCode = HttpStatusCode.Ok; SendJsonResponse(context, res); } + #endregion public void EvalGetFile(IHttpContext context, int envIndex, string filePath) @@ -4440,7 +4530,7 @@ public void EvalGetFile(IHttpContext context, int envIndex, string filePath) context.Response.StatusCode = HttpStatusCode.Ok; string fname = Path.GetFileName(filePath); - var s = Program.env[envIndex].GetLocalStreamFromPackage(filePath); + var s = Program.env[ envIndex ].GetLocalStreamFromPackage(filePath); SendStreamResponse(context, s, fname); } @@ -4458,6 +4548,7 @@ public class securityRightsClass public string value = null; public string role = null; } + public static List securityRights = null; public class securityRoleClass @@ -4475,8 +4566,12 @@ public class securityRoleClass public string semanticId = ""; public SubmodelElementCollection usage = null; public int usageEnvIndex = -1; - public securityRoleClass() { } + + public securityRoleClass() + { + } } + public static List securityRole = null; public static string securityAccessRules() @@ -4515,6 +4610,7 @@ public static string securityAccessRules() return rules; } + public static void securityInit() { withAuthentification = !Program.noSecurity; @@ -4525,10 +4621,10 @@ public static void securityInit() for (int i = 0; i < aascount; i++) { - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; if (aas.Submodels != null && aas.Submodels.Count > 0) { foreach (var smr in aas.Submodels) @@ -4553,7 +4649,7 @@ public static void securityInit() int countSme = sm.SubmodelElements.Count; for (int iSme = 0; iSme < countSme; iSme++) { - var sme = sm.SubmodelElements[iSme]; + var sme = sm.SubmodelElements[ iSme ]; if (sme is Property) continue; var smec = sme as SubmodelElementCollection; @@ -4563,7 +4659,7 @@ public static void securityInit() case "authenticationServer": for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var sme2 = smec.Value[iSmec]; + var sme2 = smec.Value[ iSmec ]; switch (sme2.IdShort) { case "endpoint": @@ -4578,35 +4674,37 @@ public static void securityInit() var f = sme2 as AasCore.Aas3_0.File; serverCertfileNames = new string[1]; serverCerts = new X509Certificate2[1]; - var s = Program.env[i].GetLocalStreamFromPackage(f.Value, init: true); + var s = Program.env[ i ].GetLocalStreamFromPackage(f.Value, init: true); if (s != null) { using (var m = new MemoryStream()) { s.CopyTo(m); var b = m.GetBuffer(); - serverCerts[0] = new X509Certificate2(b); + serverCerts[ 0 ] = new X509Certificate2(b); string[] split = f.Value.Split('/'); - serverCertfileNames[0] = split[3]; - Console.WriteLine("Loaded auth server certifcate: " + serverCertfileNames[0]); + serverCertfileNames[ 0 ] = split[ 3 ]; + Console.WriteLine("Loaded auth server certifcate: " + serverCertfileNames[ 0 ]); } } + break; } } + break; case "roleMapping": securityRights = new List(); for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var smec2 = smec.Value[iSmec] as SubmodelElementCollection; + var smec2 = smec.Value[ iSmec ] as SubmodelElementCollection; int countSmec2 = smec2.Value.Count; List subjects = new List(); for (int iSmec2 = 0; iSmec2 < countSmec2; iSmec2++) { - var smec3 = smec2.Value[iSmec2] as SubmodelElementCollection; + var smec3 = smec2.Value[ iSmec2 ] as SubmodelElementCollection; int countSmec3 = smec3.Value.Count; switch (smec3.IdShort) @@ -4614,7 +4712,7 @@ public static void securityInit() case "subjects": for (int iSmec3 = 0; iSmec3 < countSmec3; iSmec3++) { - var p = smec3.Value[iSmec3] as Property; + var p = smec3.Value[ iSmec3 ] as Property; switch (p.IdShort) { case "emailDomain": @@ -4624,14 +4722,14 @@ public static void securityInit() default: subjects.Add(p.IdShort); break; - } } + break; case "roles": for (int iSmec3 = 0; iSmec3 < countSmec3; iSmec3++) { - var p = smec3.Value[iSmec3] as Property; + var p = smec3.Value[ iSmec3 ] as Property; foreach (var s in subjects) { securityRightsClass sr = new securityRightsClass(); @@ -4640,24 +4738,28 @@ public static void securityInit() securityRights.Add(sr); } } + break; } } } + break; case "basicAuth": for (int iSmec = 0; iSmec < countSmec; iSmec++) { - if (smec.Value[iSmec] is Property p) + if (smec.Value[ iSmec ] is Property p) { securityUserName.Add(p.IdShort); securityUserPassword.Add(p.Value); } } + break; } } } + if (sm.IdShort == "SecurityMetaModelForServer" || sm.IdShort == "SecurityMetaModelForAAS") { //var smc1 = sm.SubmodelElements.FindFirstIdShortAs("accessControlPolicyPoints"); @@ -4670,21 +4772,23 @@ public static void securityInit() int countSme = smc4.Value.Count; for (int iSme = 0; iSme < countSme; iSme++) { - var sme = smc4.Value[iSme]; // actual rule + var sme = smc4.Value[ iSme ]; // actual rule var smc5 = sme as SubmodelElementCollection; var smc6 = smc5?.FindFirstIdShortAs("targetSubjectAttributes"); List role = new List(); int iRole = 0; while (smc6?.Value.Count > iRole) { - if (smc6?.Value[iRole] is Property rp) + if (smc6?.Value[ iRole ] is Property rp) { role.Add(rp); } + iRole++; } + smc6 = smc5?.FindFirstIdShortAs("permissionsPerObject"); - var smc7 = smc6?.Value[0] as SubmodelElementCollection; + var smc7 = smc6?.Value[ 0 ] as SubmodelElementCollection; var objProp = smc7?.FindFirstIdShortAs("object"); var objRef = smc7?.FindFirstIdShortAs("object"); object aasObject = null; @@ -4692,6 +4796,7 @@ public static void securityInit() { aasObject = env.AasEnv.FindReferableByReference(objRef.Value); } + var smc8 = smc7?.FindFirstIdShortAs("permission"); var smc9 = smc7?.FindFirstIdShortAs("usage"); @@ -4700,7 +4805,7 @@ public static void securityInit() Property kind = null; for (int iSmc8 = 0; iSmc8 < countSmc8; iSmc8++) { - var sme9 = smc8.Value[iSmc8]; + var sme9 = smc8.Value[ iSmc8 ]; if (sme9 is Property) kind = sme9 as Property; if (sme9 is ReferenceElement) @@ -4725,17 +4830,19 @@ public static void securityInit() src.usage = smc9; src.usageEnvIndex = i; } + if (r.IdShort.Contains(":")) { split = r.IdShort.Split(':'); - src.condition = split[0].ToLower(); - src.name = split[1]; + src.condition = split[ 0 ].ToLower(); + src.name = split[ 1 ]; } else { src.condition = ""; src.name = r.IdShort; } + if (objProp != null) { string value = objProp.Value.ToLower(); @@ -4743,21 +4850,22 @@ public static void securityInit() if (value.Contains("api")) { split = value.Split(':'); - if (split[0] == "api") + if (split[ 0 ] == "api") { - src.objType = split[0]; - src.apiOperation = split[1]; + src.objType = split[ 0 ]; + src.apiOperation = split[ 1 ]; } } + if (value.Contains("semanticid")) { split = value.Split(':'); - if (split[0] == "semanticid") + if (split[ 0 ] == "semanticid") { - src.objType = split[0]; - src.semanticId = split[1]; + src.objType = split[ 0 ]; + src.semanticId = split[ 1 ]; for (int j = 2; j < split.Length; j++) - src.semanticId += ":" + split[j]; + src.semanticId += ":" + split[ j ]; } } } @@ -4774,6 +4882,7 @@ public static void securityInit() src.submodel = aasObject as Submodel; src.objPath = src.submodel.IdShort; } + if (aasObject is ISubmodelElement smep) { IReferable rp = smep; @@ -4781,14 +4890,16 @@ public static void securityInit() string path = rp.IdShort; while (rp.Parent != null) { - rp = (IReferable)rp.Parent; + rp = (IReferable) rp.Parent; path = rp.IdShort + "." + path; } + src.submodel = rp as Submodel; src.objPath = path; } } } + src.permission = l.ToUpper(); if (kind != null) src.kind = kind.Value.ToLower(); @@ -4796,6 +4907,7 @@ public static void securityInit() securityRole.Add(src); } } + continue; } } @@ -4818,8 +4930,8 @@ public static void serverCertsInit() for (int i = 0; i < serverCertfileNames.Length; i++) { - serverCerts[i] = new X509Certificate2(serverCertfileNames[i]); - Console.WriteLine("Loaded auth server certifcate: " + Path.GetFileName(serverCertfileNames[i])); + serverCerts[ i ] = new X509Certificate2(serverCertfileNames[ i ]); + Console.WriteLine("Loaded auth server certifcate: " + Path.GetFileName(serverCertfileNames[ i ])); } } } @@ -4830,9 +4942,9 @@ public static X509Certificate2 serverCertFind(string authServerName) { for (int i = 0; i < serverCertfileNames.Length; i++) { - if (Path.GetFileName(serverCertfileNames[i]) == authServerName + ".cer") + if (Path.GetFileName(serverCertfileNames[ i ]) == authServerName + ".cer") { - return serverCerts[i]; + return serverCerts[ i ]; } } } @@ -4895,7 +5007,8 @@ public void EvalPutCd(IHttpContext context, string aasid) } // datastructure update - if (this.Packages[findAasReturn.iPackage] == null || this.Packages[findAasReturn.iPackage].AasEnv == null /*|| this.Packages[findAasReturn.iPackage].AasEnv.Assets == null*/) + if (this.Packages[ findAasReturn.iPackage ] == null || + this.Packages[ findAasReturn.iPackage ].AasEnv == null /*|| this.Packages[findAasReturn.iPackage].AasEnv.Assets == null*/) { context.Response.SendResponse(HttpStatusCode.InternalServerError, $"Error accessing internal data structures."); return; @@ -4903,10 +5016,10 @@ public void EvalPutCd(IHttpContext context, string aasid) // add Submodel context.Server.Logger.Debug($"Adding ConceptDescription with IdShort {cd.IdShort ?? "--"} and id {cd.Id?.ToString() ?? "--"}"); - var existingCd = this.Packages[findAasReturn.iPackage].AasEnv.FindConceptDescriptionById(cd.Id); + var existingCd = this.Packages[ findAasReturn.iPackage ].AasEnv.FindConceptDescriptionById(cd.Id); if (existingCd != null) - this.Packages[findAasReturn.iPackage].AasEnv.ConceptDescriptions.Remove(existingCd); - this.Packages[findAasReturn.iPackage].AasEnv.ConceptDescriptions.Add(cd); + this.Packages[ findAasReturn.iPackage ].AasEnv.ConceptDescriptions.Remove(existingCd); + this.Packages[ findAasReturn.iPackage ].AasEnv.ConceptDescriptions.Add(cd); // simple OK Program.signalNewData(2); @@ -4916,4 +5029,4 @@ public void EvalPutCd(IHttpContext context, string aasid) #endregion } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/AasxRestServer.cs b/src/AasxServerStandardBib/AasxRestServer.cs index 1ae1206c2..c08ce61e1 100644 --- a/src/AasxServerStandardBib/AasxRestServer.cs +++ b/src/AasxServerStandardBib/AasxRestServer.cs @@ -1,7 +1,5 @@ #define MICHA -using AasCore.Aas3_0; -using AasxMqttClient; using AasxServer; using AdminShellEvents; using AdminShellNS; @@ -56,11 +54,12 @@ static string translateURL(string url) return url; } - [RestResource] + [ RestResource ] public class TestResource { public static List listofRepositories = new List(); private static bool firstListOfRepositories = true; + public static void initListOfRepositories() { if (firstListOfRepositories) @@ -70,7 +69,7 @@ public static void initListOfRepositories() int aascount = AasxServer.Program.env.Length; for (int i = 0; i < aascount; i++) { - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env?.AasEnv?.AssetAdministrationShells == null) continue; @@ -105,8 +104,8 @@ public static void initListOfRepositories() } // query - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/queryregistry/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/queryregistry/(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/queryregistry/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/queryregistry/(/|)$") ] public IHttpContext Queryregistry(IHttpContext context) { allowCORS(context); @@ -143,20 +142,15 @@ public IHttpContext Queryregistry(IHttpContext context) { if (query != "") { - task = Task.Run(async () => - { - response = await client.GetAsync(requestPath, HttpCompletionOption.ResponseHeadersRead); - } - ); + task = Task.Run(async () => { response = await client.GetAsync(requestPath, HttpCompletionOption.ResponseHeadersRead); } + ); } else { - task = Task.Run(async () => - { - response = await client.PostAsync(requestPath, new StringContent(context.Request.Payload)); - } - ); + task = Task.Run(async () => { response = await client.PostAsync(requestPath, new StringContent(context.Request.Payload)); } + ); } + task.Wait(); if (response.IsSuccessStatusCode) { @@ -169,6 +163,7 @@ public IHttpContext Queryregistry(IHttpContext context) { error = true; } + if (error) result += "\nerror " + requestPath + "\n\n"; } @@ -189,22 +184,23 @@ private static bool comp(string op, string left, string right) right = right.Substring(1, rightlen - 2); right = right.Replace("><", " "); var split = right.Split(' '); - if (split.Count() == 3 && split[0] == "right") + if (split.Count() == 3 && split[ 0 ] == "right") { - if (left.Contains(split[1])) + if (left.Contains(split[ 1 ])) { - right = split[2]; + right = split[ 2 ]; rightlen = right.Length; - int found = left.IndexOf(split[1]); - found += split[1].Length; + int found = left.IndexOf(split[ 1 ]); + found += split[ 1 ].Length; string l = ""; - while (char.IsWhiteSpace(left[found]) && found < leftlen - 1) + while (char.IsWhiteSpace(left[ found ]) && found < leftlen - 1) found++; - while (char.IsDigit(left[found]) && found < leftlen - 1) + while (char.IsDigit(left[ found ]) && found < leftlen - 1) { - l += left[found]; + l += left[ found ]; found++; } + left = l; leftlen = left.Length; } @@ -232,6 +228,7 @@ private static bool comp(string op, string left, string right) left = left.Substring(leftlen - checkLen, checkLen); right = check; } + break; default: if (right.Substring(rightlen - 1, 1) == "*") @@ -245,9 +242,11 @@ private static bool comp(string op, string left, string right) right = check; } } + break; } } + if (op == "==") return left == right; return left != right; @@ -266,7 +265,7 @@ private static bool comp(string op, string left, string right) { string legal = "012345679."; - foreach (var c in left+right) + foreach (var c in left + right) { if (Char.IsDigit(c)) continue; @@ -275,6 +274,7 @@ private static bool comp(string op, string left, string right) if (!legal.Contains(c)) return false; } + var decSep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; // Console.WriteLine("seperator = " + decSep); left = left.Replace(".", decSep); @@ -303,6 +303,7 @@ private static bool comp(string op, string left, string right) { return false; } + return (false); } @@ -315,7 +316,7 @@ private static bool comp(string op, string left, string right) int l = Convert.ToInt32(left); int r = Convert.ToInt32(right); - switch(op) + switch (op) { case "==num": return l == r; @@ -335,6 +336,7 @@ private static bool comp(string op, string left, string right) { return false; } + return (false); case "contains": return left.Contains(right); @@ -362,21 +364,22 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm error = true; else { - if (split[0] != "SELECT:") + if (split[ 0 ] != "SELECT:") error = true; // if (split[1] != "aas" && split[1] != "submodel") // error = true; - if (split[2] != "FROM:") + if (split[ 2 ] != "FROM:") error = true; - if (split[3] != "registry") + if (split[ 3 ] != "registry") error = true; - if (split[4] != "WHERE:") + if (split[ 4 ] != "WHERE:") error = true; - if (split[5] != "submodelelement" && split[5] != "submodel" && split[5] != "aas") + if (split[ 5 ] != "submodelelement" && split[ 5 ] != "submodel" && split[ 5 ] != "aas") error = true; - if (split[6] != "AND" && split[6] != "OR") + if (split[ 6 ] != "AND" && split[ 6 ] != "OR") error = true; } + if (error) { result += "ERROR\n"; @@ -394,9 +397,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm result += "registry endpoint " + AasxServer.Program.externalBlazor + "\n"; - var sSplit = split[1].Split(' '); - string select = sSplit[0]; - string selectParameters = split[1].Substring(select.Length); + var sSplit = split[ 1 ].Split(' '); + string select = sSplit[ 0 ]; + string selectParameters = split[ 1 ].Substring(select.Length); string whereAasCondition = ""; string whereSmCondition = ""; string whereSmeCondition = ""; @@ -404,23 +407,25 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm List whereSmOperations = new List(); List whereSmeOperations = new List(); - if (split[5] == "aas") + if (split[ 5 ] == "aas") { - whereAasCondition = split[6].ToLower(); + whereAasCondition = split[ 6 ].ToLower(); for (int i = 7; i < split.Length; i++) - whereAasOperations.Add(split[i]); + whereAasOperations.Add(split[ i ]); } - if (split[5] == "submodel") + + if (split[ 5 ] == "submodel") { - whereSmCondition = split[6].ToLower(); + whereSmCondition = split[ 6 ].ToLower(); for (int i = 7; i < split.Length; i++) - whereSmOperations.Add(split[i]); + whereSmOperations.Add(split[ i ]); } - if (split[5] == "submodelelement") + + if (split[ 5 ] == "submodelelement") { - whereSmeCondition = split[6].ToLower(); + whereSmeCondition = split[ 6 ].ToLower(); for (int i = 7; i < split.Length; i++) - whereSmeOperations.Add(split[i]); + whereSmeOperations.Add(split[ i ]); } int totalFound = 0; @@ -458,6 +463,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm break; } } + if (sme2 is ReferenceElement r) { if (r.IdShort.Substring(0, 4).ToLower() == "ref_") @@ -483,9 +489,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2].Replace("\"", ""); + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ].Replace("\"", ""); } string compare = ""; @@ -501,6 +507,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm compare = assetID; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -513,8 +520,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm break; } } + if ((whereAasCondition == "and" && conditionsTrue == whereAasOperations.Count) - || (whereAasCondition == "or" && conditionsTrue != 0)) + || (whereAasCondition == "or" && conditionsTrue != 0)) { foundInAas++; totalFound++; @@ -552,6 +560,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm break; } } + if (sme2 is SubmodelElementCollection smc2) { switch (smc2.IdShort) @@ -565,9 +574,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm // check, if access to submodel is allowed var accessSubmodel = !AasxRestServerLibrary.AasxHttpContextHelper.withAuthentification || - AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( - null, "/submodels", "READ", - submodelIdShort, "semanticid", semanticID); + AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( + null, "/submodels", "READ", + submodelIdShort, "semanticid", semanticID); if (!accessSubmodel) continue; @@ -584,9 +593,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2].Replace("\"", ""); + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ].Replace("\"", ""); } string compare = ""; @@ -602,6 +611,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm compare = semanticID; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -614,8 +624,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm break; } } + if ((whereAasCondition == "and" && conditionsTrue == whereAasOperations.Count) - || (whereAasCondition == "or" && conditionsTrue != 0)) + || (whereAasCondition == "or" && conditionsTrue != 0)) { foundInSubmodel++; totalFound++; @@ -635,7 +646,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm { while (iLevel < level.Count) { - var sme = level[iLevel]; + var sme = level[ iLevel ]; int conditionsTrue = 0; foreach (var wo in whereSmeOperations) @@ -646,9 +657,9 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2].Replace("\"", ""); + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ].Replace("\"", ""); } string compare = ""; @@ -663,9 +674,10 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm break; case "%semanticid": if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0) - compare = sme.SemanticId.Keys[0].Value; + compare = sme.SemanticId.Keys[ 0 ].Value; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -680,7 +692,7 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm } if ((whereSmeCondition == "and" && conditionsTrue == whereSmeOperations.Count) - || (whereSmeCondition == "or" && conditionsTrue != 0)) + || (whereSmeCondition == "or" && conditionsTrue != 0)) { foundInAas++; foundInSubmodel++; @@ -699,15 +711,16 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm { for (int iMlp = 0; iMlp < mlp.Value.Count; iMlp++) { - result += " [" + mlp.Value[iMlp].Language + "]" + - mlp.Value[iMlp].Text; + result += " [" + mlp.Value[ iMlp ].Language + "]" + + mlp.Value[ iMlp ].Text; } - } } + result += "\n"; } } + if (sme is SubmodelElementCollection smc2) { stack.Add(level); @@ -715,23 +728,26 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm depth++; string smcSemanticId = ""; if (smc2.SemanticId != null && smc2.SemanticId.Keys != null && smc2.SemanticId.Keys.Count != 0) - smcSemanticId = smc2.SemanticId.Keys[0].Value; + smcSemanticId = smc2.SemanticId.Keys[ 0 ].Value; level = smc2.Value; iLevel = 0; continue; } + iLevel++; } + depth--; if (depth >= 0) { - level = stack[depth]; + level = stack[ depth ]; stack.RemoveAt(depth); - iLevel = iStack[depth]; + iLevel = iStack[ depth ]; iStack.RemoveAt(depth); } } } + if (select == "submodel") { if (foundInSubmodel > 0) @@ -741,22 +757,27 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm { result += " " + "" + submodelEndpoint + ""; } + if (selectParameters.Contains("%idshort")) { result += " " + submodelIdShort; } + if (selectParameters.Contains("%id")) { result += " " + submodelID; } + if (selectParameters.Contains("%semanticid")) { result += " " + semanticID; } + result += "\n"; } } } + if (select == "aas") { if (foundInAas > 0) @@ -765,25 +786,29 @@ public static string runQueryRegistryOnly(string query, string restPayload, Subm if (!selectParameters.Contains("!endpoint")) { result += " " + "" + aasEndpoint + ""; - } + if (selectParameters.Contains("%idshort")) { result += " " + aasIdShort; } + if (selectParameters.Contains("%id")) { result += " " + aasID; } + if (selectParameters.Contains("%aasetid")) { result += " " + assetID; } + result += "\n"; } } } } + result += "registry totalfound " + totalFound + " " + AasxServer.Program.externalBlazor + "\n"; } @@ -805,7 +830,8 @@ public static string runQuery(string query, string restPayload) result += "WHERE:
"; result += "aas | submodel | submodelelement (element to search for)
"; result += "OR | AND
"; - result += "%id | %assetid | %idshort | %value | %semanticid | %path | %semanticidpath == | != | > | >= | < | <= | contains | !contains \"value\"
"; + result += + "%id | %assetid | %idshort | %value | %semanticid | %path | %semanticidpath == | != | > | >= | < | <= | contains | !contains \"value\"
"; result += "(last line may be repeated after OR and AND)
"; result += "(options after SELECT: aas [ %id | %idshort | %assetid | !endpoint ])
"; result += "(options after SELECT: submodel [ %id | %idshort | %semanticid | !endpoint ])
"; @@ -863,9 +889,11 @@ public static string runQuery(string query, string restPayload) nested.Add(next); next = ""; } + next += sp + "\n"; last = s; } + if (next != "") nested.Add(next); @@ -914,21 +942,23 @@ public static string runQuery(string query, string restPayload) countLines = 0; break; } + switch (last) { case "select:": var sSplit = s.Split(' '); - select = sSplit[0]; + select = sSplit[ 0 ]; selectParameters = s.Substring(select.Length); break; case "from:": var fromsplit = sp.Split(' '); - from = fromsplit[0].ToLower(); + from = fromsplit[ 0 ].ToLower(); if (from == "aas" || from == "submodel") { if (fromsplit.Length == 2) - fromId = fromsplit[1].Replace("\"", ""); + fromId = fromsplit[ 1 ].Replace("\"", ""); } + break; case "where:": switch (countLines) @@ -949,6 +979,7 @@ public static string runQuery(string query, string restPayload) whereSmeCondition = sp.Replace("\"", "").ToLower(); break; } + break; default: switch (whereElement) @@ -963,11 +994,14 @@ public static string runQuery(string query, string restPayload) whereSmeOperations.Add(sp.Replace("\"", "")); break; } + break; } + countLines++; break; } + if (last != "where:") last = s; } @@ -1010,7 +1044,7 @@ public static string runQuery(string query, string restPayload) for (int i = 0; i < aascount; i++) { int foundInAas = 0; - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env?.AasEnv?.AssetAdministrationShells == null) continue; @@ -1042,9 +1076,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; } string compare = ""; @@ -1061,6 +1095,7 @@ public static string runQuery(string query, string restPayload) compare = aas.AssetInformation.GlobalAssetId; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1073,8 +1108,9 @@ public static string runQuery(string query, string restPayload) break; } } + if ((whereAasCondition == "and" && conditionsTrue == whereAasOperations.Count) - || (whereAasCondition == "or" && conditionsTrue != 0)) + || (whereAasCondition == "or" && conditionsTrue != 0)) { if (whereSmCondition == "") { @@ -1088,6 +1124,7 @@ public static string runQuery(string query, string restPayload) storeAas.Add(aas); } } + if (select == "repository") { foundInRepository++; @@ -1125,13 +1162,13 @@ public static string runQuery(string query, string restPayload) // check, if access to submodel is allowed var accessSubmodel = !AasxRestServerLibrary.AasxHttpContextHelper.withAuthentification || - AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( - null, "/submodels", "READ", - sm.IdShort, "sm", sm); + AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( + null, "/submodels", "READ", + sm.IdShort, "sm", sm); string smSemanticId = ""; if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - smSemanticId = sm.SemanticId.Keys[0].Value; + smSemanticId = sm.SemanticId.Keys[ 0 ].Value; int foundInSubmodel = 0; if (whereSmCondition != "" && accessSubmodel) @@ -1145,9 +1182,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; string compare = ""; switch (attr) @@ -1161,9 +1198,10 @@ public static string runQuery(string query, string restPayload) case "%semanticid": compare = ""; if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - compare = sm.SemanticId.Keys[0].Value; + compare = sm.SemanticId.Keys[ 0 ].Value; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1179,7 +1217,7 @@ public static string runQuery(string query, string restPayload) } if ((whereSmCondition == "and" && conditionsTrue == whereSmOperations.Count) - || (whereSmCondition == "or" && conditionsTrue != 0)) + || (whereSmCondition == "or" && conditionsTrue != 0)) { if (whereSmeCondition == "") { @@ -1189,11 +1227,12 @@ public static string runQuery(string query, string restPayload) { if (!storeSubmodels.Contains(sm)) storeSubmodels.Add(sm); - } + foundInSubmodel++; totalFound++; } + if (select == "aas" || select == "aasid") { if (storeResult) @@ -1201,9 +1240,11 @@ public static string runQuery(string query, string restPayload) if (!storeAas.Contains(aas)) storeAas.Add(aas); } + foundInAas++; totalFound++; } + if (select == "repository") { foundInRepository++; @@ -1232,7 +1273,7 @@ public static string runQuery(string query, string restPayload) { while (iLevel < level.Count) { - var sme = level[iLevel]; + var sme = level[ iLevel ]; // check, if access to submodelelement is allowed string _path = sm.IdShort + "."; @@ -1240,9 +1281,9 @@ public static string runQuery(string query, string restPayload) _path += path; _path = _path.Replace("/", "."); var accessSme = !AasxRestServerLibrary.AasxHttpContextHelper.withAuthentification || - AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( - null, "/submodelelements", "READ", - _path + sme.IdShort, "", sm); + AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( + null, "/submodelelements", "READ", + _path + sme.IdShort, "", sm); if (accessSme) { @@ -1255,9 +1296,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; } string compare = ""; @@ -1272,7 +1313,7 @@ public static string runQuery(string query, string restPayload) break; case "%semanticid": if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0) - compare = sme.SemanticId.Keys[0].Value; + compare = sme.SemanticId.Keys[ 0 ].Value; break; case "%path": attrValue = attrValue.Replace(".", "/"); @@ -1282,6 +1323,7 @@ public static string runQuery(string query, string restPayload) compare = smSemanticId + "." + semanticIdPath; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1296,7 +1338,7 @@ public static string runQuery(string query, string restPayload) } if ((whereSmeCondition == "and" && conditionsTrue == whereSmeOperations.Count) - || (whereSmeCondition == "or" && conditionsTrue != 0)) + || (whereSmeCondition == "or" && conditionsTrue != 0)) { if (storeSmesLast.Count == 0 || (storeSmesLast.Count != 0 && storeSmesLast.Contains(sme))) { @@ -1307,18 +1349,21 @@ public static string runQuery(string query, string restPayload) if (!storeSmes.Contains(sme)) storeSmes.Add(sme); } + result += "submodelelement found" + " 1"; if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/submodels/" + Base64UrlEncoder.Encode(sm.Id) + - "/submodelelements/" + path.Replace("/", ".") + sme.IdShort; + "/submodels/" + Base64UrlEncoder.Encode(sm.Id) + + "/submodelelements/" + path.Replace("/", ".") + sme.IdShort; result += " " + "" + link + ""; } + if (selectParameters.Contains("%idshort")) { result += " " + sme.IdShort; } + if (selectParameters.Contains("%value")) { if (sme is Property p) @@ -1331,25 +1376,28 @@ public static string runQuery(string query, string restPayload) { for (int iMlp = 0; iMlp < mlp.Value.Count; iMlp++) { - result += " [" + mlp.Value[iMlp].Language + "]" + - mlp.Value[iMlp].Text; + result += " [" + mlp.Value[ iMlp ].Language + "]" + + mlp.Value[ iMlp ].Text; } - } } } + if (selectParameters.Contains("%semanticid")) { if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0) - result += " " + sme.SemanticId.Keys[0].Value; + result += " " + sme.SemanticId.Keys[ 0 ].Value; } + if (selectParameters.Contains("%path")) { result += " " + aas.IdShort + "/" + sm.IdShort + "/" + path + sme.IdShort; } + result += "\n"; totalFound++; } + if (select == "submodel" || select == "submodelid") { if (storeResult) @@ -1357,9 +1405,11 @@ public static string runQuery(string query, string restPayload) if (!storeSubmodels.Contains(sm)) storeSubmodels.Add(sm); } + foundInSubmodel++; totalFound++; } + if (select == "aas" || select == "aasid") { if (storeResult) @@ -1367,9 +1417,11 @@ public static string runQuery(string query, string restPayload) if (!storeAas.Contains(aas)) storeAas.Add(aas); } + foundInAas++; totalFound++; } + if (select == "repository") { foundInRepository++; @@ -1389,24 +1441,26 @@ public static string runQuery(string query, string restPayload) path += smc.IdShort + "/"; string smcSemanticId = ""; if (smc.SemanticId != null && smc.SemanticId.Keys != null && smc.SemanticId.Keys.Count != 0) - smcSemanticId = smc.SemanticId.Keys[0].Value; + smcSemanticId = smc.SemanticId.Keys[ 0 ].Value; semanticIdPath += smcSemanticId + "."; level = smc.Value; iLevel = 0; continue; } + iLevel++; } + depth--; if (depth >= 0) { - level = stack[depth]; + level = stack[ depth ]; stack.RemoveAt(depth); - iLevel = iStack[depth]; + iLevel = iStack[ depth ]; iStack.RemoveAt(depth); - path = pathStack[depth]; + path = pathStack[ depth ]; pathStack.RemoveAt(depth); - semanticIdPath = semanticIdPathStack[depth]; + semanticIdPath = semanticIdPathStack[ depth ]; semanticIdPathStack.RemoveAt(depth); } } @@ -1419,24 +1473,29 @@ public static string runQuery(string query, string restPayload) if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/submodels/" + Base64UrlEncoder.Encode(sm.Id); + "/submodels/" + Base64UrlEncoder.Encode(sm.Id); result += " " + "" + link + ""; } + if (selectParameters.Contains("%id ")) { result += " " + sm.Id; } + if (selectParameters.Contains("%idshort")) { result += " " + sm.IdShort; } + if (selectParameters.Contains("%semanticid")) { if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - result += " " + sm.SemanticId.Keys[0].Value; + result += " " + sm.SemanticId.Keys[ 0 ].Value; } + result += "\n"; } + if (select == "submodelid" && foundInSubmodel != 0 && accessSubmodel) result += "%id == \"" + sm.Id + "\"\n"; } // submodels @@ -1448,24 +1507,29 @@ public static string runQuery(string query, string restPayload) if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/shells/" + Base64UrlEncoder.Encode(aas.Id); + "/shells/" + Base64UrlEncoder.Encode(aas.Id); result += " " + "" + link + ""; } + if (selectParameters.Contains("%id ")) { result += " " + aas.Id; } + if (selectParameters.Contains("%idshort")) { result += " " + aas.IdShort; } + if (selectParameters.Contains("%assetid")) { if (aas.AssetInformation.GlobalAssetId != null) result += " " + aas.AssetInformation.GlobalAssetId; } + result += "\n"; } + if (select == "aasid" && foundInAas != 0) result += "%id == \"" + aas.Id + "\"\n"; } // AAS @@ -1506,15 +1570,15 @@ public static string runQuery(string query, string restPayload) { int foundInAas = 0; - var aasDB = aasDBList[i]; + var aasDB = aasDBList[ i ]; AssetAdministrationShell aas = new AssetAdministrationShell( id: aasDB.AasId, idShort: aasDB.Idshort, /*assetInformation: new AssetInformation(AssetKind.Type, - new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, + new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, aasDB.AssetId) })*/ assetInformation: new AssetInformation(AssetKind.Type, aasDB.AssetId) - ); + ); { if (storeAasLast.Count != 0) @@ -1540,9 +1604,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; } string compare = ""; @@ -1559,6 +1623,7 @@ public static string runQuery(string query, string restPayload) compare = aas.AssetInformation.GlobalAssetId; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1571,8 +1636,9 @@ public static string runQuery(string query, string restPayload) break; } } + if ((whereAasCondition == "and" && conditionsTrue == whereAasOperations.Count) - || (whereAasCondition == "or" && conditionsTrue != 0)) + || (whereAasCondition == "or" && conditionsTrue != 0)) { if (whereSmCondition == "") { @@ -1586,6 +1652,7 @@ public static string runQuery(string query, string restPayload) storeAas.Add(aas); } } + if (select == "repository") { foundInRepository++; @@ -1600,9 +1667,9 @@ public static string runQuery(string query, string restPayload) } var submodelDBList = db.SubmodelSets - .OrderBy(sm => sm.SubmodelNum) - .Where(sm => sm.AasNum == aasDB.AasNum) - .ToList(); + .OrderBy(sm => sm.SubmodelNum) + .Where(sm => sm.AasNum == aasDB.AasNum) + .ToList(); foreach (var submodelDB in submodelDBList) { @@ -1622,13 +1689,13 @@ public static string runQuery(string query, string restPayload) // check, if access to submodel is allowed var accessSubmodel = !AasxRestServerLibrary.AasxHttpContextHelper.withAuthentification || - AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( - null, "/submodels", "READ", - sm.IdShort, "sm", sm); + AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( + null, "/submodels", "READ", + sm.IdShort, "sm", sm); string smSemanticId = ""; if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - smSemanticId = sm.SemanticId.Keys[0].Value; + smSemanticId = sm.SemanticId.Keys[ 0 ].Value; int foundInSubmodel = 0; if (whereSmCondition != "" && accessSubmodel) @@ -1642,9 +1709,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; string compare = ""; switch (attr) @@ -1658,9 +1725,10 @@ public static string runQuery(string query, string restPayload) case "%semanticid": compare = ""; if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - compare = sm.SemanticId.Keys[0].Value; + compare = sm.SemanticId.Keys[ 0 ].Value; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1676,7 +1744,7 @@ public static string runQuery(string query, string restPayload) } if ((whereSmCondition == "and" && conditionsTrue == whereSmOperations.Count) - || (whereSmCondition == "or" && conditionsTrue != 0)) + || (whereSmCondition == "or" && conditionsTrue != 0)) { if (whereSmeCondition == "") { @@ -1686,11 +1754,12 @@ public static string runQuery(string query, string restPayload) { if (!storeSubmodels.Contains(sm)) storeSubmodels.Add(sm); - } + foundInSubmodel++; totalFound++; } + if (select == "aas" || select == "aasid") { if (storeResult) @@ -1698,9 +1767,11 @@ public static string runQuery(string query, string restPayload) if (!storeAas.Contains(aas)) storeAas.Add(aas); } + foundInAas++; totalFound++; } + if (select == "repository") { foundInRepository++; @@ -1729,7 +1800,7 @@ public static string runQuery(string query, string restPayload) { while (iLevel < level.Count) { - var sme = level[iLevel]; + var sme = level[ iLevel ]; // check, if access to submodelelement is allowed string _path = sm.IdShort + "."; @@ -1737,9 +1808,9 @@ public static string runQuery(string query, string restPayload) _path += path; _path = _path.Replace("/", "."); var accessSme = !AasxRestServerLibrary.AasxHttpContextHelper.withAuthentification || - AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( - null, "/submodelelements", "READ", - _path + sme.IdShort, "", sm); + AasxRestServerLibrary.AasxHttpContextHelper.checkAccessLevel( + null, "/submodelelements", "READ", + _path + sme.IdShort, "", sm); if (accessSme) { @@ -1752,9 +1823,9 @@ public static string runQuery(string query, string restPayload) split = wo.Split(' '); if (split.Length == 3) { - attr = split[0]; - op = split[1]; - attrValue = split[2]; + attr = split[ 0 ]; + op = split[ 1 ]; + attrValue = split[ 2 ]; } string compare = ""; @@ -1769,7 +1840,7 @@ public static string runQuery(string query, string restPayload) break; case "%semanticid": if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0) - compare = sme.SemanticId.Keys[0].Value; + compare = sme.SemanticId.Keys[ 0 ].Value; break; case "%path": attrValue = attrValue.Replace(".", "/"); @@ -1779,6 +1850,7 @@ public static string runQuery(string query, string restPayload) compare = smSemanticId + "." + semanticIdPath; break; } + if (comp(op, compare, attrValue)) { conditionsTrue++; @@ -1793,7 +1865,7 @@ public static string runQuery(string query, string restPayload) } if ((whereSmeCondition == "and" && conditionsTrue == whereSmeOperations.Count) - || (whereSmeCondition == "or" && conditionsTrue != 0)) + || (whereSmeCondition == "or" && conditionsTrue != 0)) { if (storeSmesLast.Count == 0 || (storeSmesLast.Count != 0 && storeSmesLast.Contains(sme))) { @@ -1804,18 +1876,21 @@ public static string runQuery(string query, string restPayload) if (!storeSmes.Contains(sme)) storeSmes.Add(sme); } + result += "submodelelement found" + " 1"; if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/submodels/" + Base64UrlEncoder.Encode(sm.Id) + - "/submodelelements/" + path.Replace("/", ".") + sme.IdShort; + "/submodels/" + Base64UrlEncoder.Encode(sm.Id) + + "/submodelelements/" + path.Replace("/", ".") + sme.IdShort; result += " " + "" + link + ""; } + if (selectParameters.Contains("%idshort")) { result += " " + sme.IdShort; } + if (selectParameters.Contains("%value")) { if (sme is Property p) @@ -1828,25 +1903,28 @@ public static string runQuery(string query, string restPayload) { for (int iMlp = 0; iMlp < mlp.Value.Count; iMlp++) { - result += " [" + mlp.Value[iMlp].Language + "]" + - mlp.Value[iMlp].Text; + result += " [" + mlp.Value[ iMlp ].Language + "]" + + mlp.Value[ iMlp ].Text; } - } } } + if (selectParameters.Contains("%semanticid")) { if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0) - result += " " + sme.SemanticId.Keys[0].Value; + result += " " + sme.SemanticId.Keys[ 0 ].Value; } + if (selectParameters.Contains("%path")) { result += " " + aas.IdShort + "/" + sm.IdShort + "/" + path + sme.IdShort; } + result += "\n"; totalFound++; } + if (select == "submodel" || select == "submodelid") { if (storeResult) @@ -1854,9 +1932,11 @@ public static string runQuery(string query, string restPayload) if (!storeSubmodels.Contains(sm)) storeSubmodels.Add(sm); } + foundInSubmodel++; totalFound++; } + if (select == "aas" || select == "aasid") { if (storeResult) @@ -1864,9 +1944,11 @@ public static string runQuery(string query, string restPayload) if (!storeAas.Contains(aas)) storeAas.Add(aas); } + foundInAas++; totalFound++; } + if (select == "repository") { foundInRepository++; @@ -1886,24 +1968,26 @@ public static string runQuery(string query, string restPayload) path += smc.IdShort + "/"; string smcSemanticId = ""; if (smc.SemanticId != null && smc.SemanticId.Keys != null && smc.SemanticId.Keys.Count != 0) - smcSemanticId = smc.SemanticId.Keys[0].Value; + smcSemanticId = smc.SemanticId.Keys[ 0 ].Value; semanticIdPath += smcSemanticId + "."; level = smc.Value; iLevel = 0; continue; } + iLevel++; } + depth--; if (depth >= 0) { - level = stack[depth]; + level = stack[ depth ]; stack.RemoveAt(depth); - iLevel = iStack[depth]; + iLevel = iStack[ depth ]; iStack.RemoveAt(depth); - path = pathStack[depth]; + path = pathStack[ depth ]; pathStack.RemoveAt(depth); - semanticIdPath = semanticIdPathStack[depth]; + semanticIdPath = semanticIdPathStack[ depth ]; semanticIdPathStack.RemoveAt(depth); } } @@ -1916,24 +2000,29 @@ public static string runQuery(string query, string restPayload) if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/submodels/" + Base64UrlEncoder.Encode(sm.Id); + "/submodels/" + Base64UrlEncoder.Encode(sm.Id); result += " " + "" + link + ""; } + if (selectParameters.Contains("%id ")) { result += " " + sm.Id; } + if (selectParameters.Contains("%idshort")) { result += " " + sm.IdShort; } + if (selectParameters.Contains("%semanticid")) { if (sm.SemanticId != null && sm.SemanticId.Keys != null && sm.SemanticId.Keys.Count != 0) - result += " " + sm.SemanticId.Keys[0].Value; + result += " " + sm.SemanticId.Keys[ 0 ].Value; } + result += "\n"; } + if (select == "submodelid" && foundInSubmodel != 0 && accessSubmodel) result += "%id == \"" + sm.Id + "\"\n"; } // submodels @@ -1945,24 +2034,29 @@ public static string runQuery(string query, string restPayload) if (!selectParameters.Contains("!endpoint")) { string link = AasxServer.Program.externalBlazor + - "/shells/" + Base64UrlEncoder.Encode(aas.Id); + "/shells/" + Base64UrlEncoder.Encode(aas.Id); result += " " + "" + link + ""; } + if (selectParameters.Contains("%id ")) { result += " " + aas.Id; } + if (selectParameters.Contains("%idshort")) { result += " " + aas.IdShort; } + if (selectParameters.Contains("%assetid")) { if (aas.AssetInformation.GlobalAssetId != null) result += " " + aas.AssetInformation.GlobalAssetId; } + result += "\n"; } + if (select == "aasid" && foundInAas != 0) result += "%id == \"" + aas.Id + "\"\n"; } // AAS @@ -1995,9 +2089,8 @@ public static string runQuery(string query, string restPayload) } // query - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/query/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/query/(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/query/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/query/(/|)$") ] public IHttpContext Query(IHttpContext context) { allowCORS(context); @@ -2016,9 +2109,8 @@ public IHttpContext Query(IHttpContext context) } // exit application - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/exit/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/exit/([^/]+)(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/exit/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/exit/([^/]+)(/|)$") ] public IHttpContext Exit(IHttpContext context) { string restPath = context.Request.PathInfo; @@ -2038,8 +2130,11 @@ public IHttpContext Exit(IHttpContext context) catch { error = true; - }; + } + + ; } + if (secret1 == null || requestSecret1 != secret1) error = true; @@ -2054,9 +2149,8 @@ public IHttpContext Exit(IHttpContext context) } // set secret string to write to API - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/secret/([^/]+)/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/secret/([^/]+)/([^/]+)(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/secret/([^/]+)/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/secret/([^/]+)/([^/]+)(/|)$") ] public IHttpContext Secret(IHttpContext context) { string requestSecret1 = null; @@ -2069,8 +2163,8 @@ public IHttpContext Secret(IHttpContext context) string[] split = restPath.Split('/'); if (split.Count() == 2) { - requestSecret1 = split[0]; - requestSecret2 = split[1]; + requestSecret1 = split[ 0 ]; + requestSecret2 = split[ 1 ]; } if (System.IO.File.Exists("SECRET.DAT")) @@ -2085,8 +2179,11 @@ public IHttpContext Secret(IHttpContext context) catch { error = true; - }; + } + + ; } + if (secret1 == null || requestSecret1 != secret1) error = true; @@ -2112,6 +2209,7 @@ public IHttpContext Secret(IHttpContext context) public static int varInt1 = -100; // -100..100 public static int varInt2 = 0; // 0..10 public static double varFloat3 = 0; // sin(varInt1/30); + class testData { public int varInt1; @@ -2131,8 +2229,7 @@ void sendJson(IHttpContext context, object o) context.Response.SendResponse(buffer); } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/data4(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/data4(/|)$") ] public IHttpContext GetData4(IHttpContext context) { varInt1++; @@ -2147,7 +2244,7 @@ public IHttpContext GetData4(IHttpContext context) testData td = new testData(); td.varInt1 = varInt1; td.varInt2 = varInt2; - td.varFloat3 = (float)varFloat3; + td.varFloat3 = (float) varFloat3; sendJson(context, td); return context; @@ -2202,7 +2299,6 @@ public static void add(IReferable o, string op, ISubmodel rootSubmodel, ulong ch if (keys.Count != 0) keys.Remove(keys.Last()); #else - while (smec != null) { keys.Add(AdminShellV20.Key.CreateNew("SMEC", false, "SMEC", smec.IdShort)); @@ -2231,10 +2327,10 @@ public static void add(IReferable o, string op, ISubmodel rootSubmodel, ulong ch } o.IdShort = path; */ - deletedList.Add(new DeletedListItem() { sm = rootSubmodel, rf = o }); - if (deletedList.Count > 1000 && deletedList[0].rf != null) + deletedList.Add(new DeletedListItem() {sm = rootSubmodel, rf = o}); + if (deletedList.Count > 1000 && deletedList[ 0 ].rf != null) { - olderDeletedTimeStamp = deletedList[0].rf.TimeStamp; + olderDeletedTimeStamp = deletedList[ 0 ].rf.TimeStamp; deletedList.RemoveAt(0); } } @@ -2244,8 +2340,7 @@ public static void add(IReferable o, string op, ISubmodel rootSubmodel, ulong ch public static string posttimeseriesPayload = ""; - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/posttimeseries(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/posttimeseries(/|)$") ] public IHttpContext posttimeseries(IHttpContext context) { Console.WriteLine("posttimeseries:"); @@ -2259,8 +2354,7 @@ public IHttpContext posttimeseries(IHttpContext context) return context; } - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/calculatecfp/aas/([^/]+)(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/calculatecfp/aas/([^/]+)(/|)$") ] public IHttpContext calculatecfp(IHttpContext context) { string restPath = context.Request.PathInfo; @@ -2271,11 +2365,11 @@ public IHttpContext calculatecfp(IHttpContext context) { // specific AAS string[] split = restPath.Split('/'); - if (split[2] == "aas") + if (split[ 2 ] == "aas") { try { - if (!int.TryParse(split[3], out aasIndex)) + if (!int.TryParse(split[ 3 ], out aasIndex)) aasIndex = -1; if (aasIndex >= 0) { @@ -2283,7 +2377,9 @@ public IHttpContext calculatecfp(IHttpContext context) result = "OK"; } } - catch { } + catch + { + } } } @@ -2299,21 +2395,18 @@ public IHttpContext calculatecfp(IHttpContext context) private static bool _setAllParentsExecuted = false; - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/values(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/time/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/deltasecs/(\\d+)(/|)$")] - - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/values(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/time/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/deltasecs/(\\d+)(/|)$")] - - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/values(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/time/([^/]+)(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/deltasecs/(\\d+)(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/values(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/time/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/deltasecs/(\\d+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/values(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/time/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/geteventmessages/aas/([^/]+)/deltasecs/(\\d+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/values(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/time/([^/]+)(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/([^/]+)/geteventmessages/deltasecs/(\\d+)(/|)$") ] public IHttpContext GetEventMessages(IHttpContext context) { // @@ -2330,11 +2423,11 @@ public IHttpContext GetEventMessages(IHttpContext context) { // specific AAS string[] split = restPath.Split('/'); - if (split[2] == "aas") + if (split[ 2 ] == "aas") { try { - if (!int.TryParse(split[3], out aasIndex)) + if (!int.TryParse(split[ 3 ], out aasIndex)) aasIndex = -1; if (aasIndex >= 0) { @@ -2343,18 +2436,21 @@ public IHttpContext GetEventMessages(IHttpContext context) { if (i != 2 && i != 3) { - restPath += "/" + split[i]; + restPath += "/" + split[ i ]; } } } } - catch { } + catch + { + } } - if (split[1] == "aas") + + if (split[ 1 ] == "aas") { try { - if (!int.TryParse(split[2], out aasIndex)) + if (!int.TryParse(split[ 2 ], out aasIndex)) aasIndex = -1; if (aasIndex >= 0) { @@ -2363,12 +2459,14 @@ public IHttpContext GetEventMessages(IHttpContext context) { if (i != 1 && i != 2) { - restPath += "/" + split[i]; + restPath += "/" + split[ i ]; } } } } - catch { } + catch + { + } } } @@ -2384,8 +2482,11 @@ public IHttpContext GetEventMessages(IHttpContext context) { minimumDate = DateTime.Parse(restPath.Substring("/geteventmessages/time/".Length)).ToUniversalTime(); } - catch { } + catch + { + } } + if (restPath.StartsWith("/geteventmessages/deltasecs/")) { try @@ -2394,7 +2495,9 @@ public IHttpContext GetEventMessages(IHttpContext context) if (int.TryParse(secs, out int i)) minimumDate = DateTime.UtcNow.AddSeconds(-1.0 * i); } - catch { } + catch + { + } } } @@ -2432,7 +2535,7 @@ public IHttpContext GetEventMessages(IHttpContext context) if (aasIndex >= 0 && i != aasIndex) continue; - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env?.AasEnv?.AssetAdministrationShells == null) continue; @@ -2487,18 +2590,18 @@ public IHttpContext GetEventMessages(IHttpContext context) // var eventsOuter = new AasEventMsgEnvelope( - DateTime.UtcNow, - source: bev.GetModelReference(), - sourceSemanticId: bev.SemanticId, - observableReference: bev.Observed, - observableSemanticId: obsSemId); + DateTime.UtcNow, + source: bev.GetModelReference(), + sourceSemanticId: bev.SemanticId, + observableReference: bev.Observed, + observableSemanticId: obsSemId); // directly create lists of update value and structural change events var plStruct = new AasPayloadStructuralChange(); var plUpdate = new AasPayloadUpdateValue(); - string[] modes = { "CREATE", "UPDATE" }; + string[] modes = {"CREATE", "UPDATE"}; // // Check for deletes @@ -2614,7 +2717,7 @@ static void GetEventMsgRecurseDiff( if (mode == "CREATE") { - if (/* doCreateDelete && */ plStruct != null) + if ( /* doCreateDelete && */ plStruct != null) plStruct.Changes.Add(new AasPayloadStructuralChangeItem( count: 1, timeStamp: sme.TimeStamp, @@ -2625,7 +2728,7 @@ static void GetEventMsgRecurseDiff( } else { - if (/* doUpdate && */ plUpdate != null) + if ( /* doUpdate && */ plUpdate != null) { var val = sme.ValueAsText(); if (sme is Blob blob) @@ -2651,7 +2754,7 @@ static void GetEventMsgRecurseDiff( deeper = true; } else - // + // { if (smec.Value.Count == 1) { @@ -2663,12 +2766,13 @@ static void GetEventMsgRecurseDiff( int i = 0; while (i < smec.Value.Count) { - var sme2 = smec.Value[i]; + var sme2 = smec.Value[ i ]; if (sme2.TimeStamp != smec.TimeStamp) { deeper = true; break; } + i++; } } @@ -2680,13 +2784,14 @@ static void GetEventMsgRecurseDiff( int i = 0; while (i < smec.Value.Count) { - var sme2 = smec.Value[i]; + var sme2 = smec.Value[ i ]; GetEventMsgRecurseDiff( mode, plStruct, plUpdate, sme2, minimumDate, doUpdate, doCreateDelete, observablePath); i++; } + return; } @@ -2699,7 +2804,7 @@ static void GetEventMsgRecurseDiff( { if (sme.TimeStampCreate > minimumDate) { - if (/* doCreateDelete && */ plStruct != null) + if ( /* doCreateDelete && */ plStruct != null) plStruct.Changes.Add(new AasPayloadStructuralChangeItem( count: 1, timeStamp: sme.TimeStamp, @@ -2709,10 +2814,9 @@ static void GetEventMsgRecurseDiff( data: JsonConvert.SerializeObject(sme))); } } - else - if (sme.TimeStamp > minimumDate && sme.TimeStamp != sme.TimeStampCreate) + else if (sme.TimeStamp > minimumDate && sme.TimeStamp != sme.TimeStampCreate) { - if (/* doUpdate && */ plUpdate != null) + if ( /* doUpdate && */ plUpdate != null) plUpdate.Values.Add(new AasPayloadUpdateValueItem( path: p2, sme.ValueAsText())); @@ -2732,7 +2836,7 @@ public static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext con { // make JSON var settings = AasxIntegrationBase.AasxPluginOptionSerialization.GetDefaultJsonSettings( - new[] { typeof(AdminShellEvents.AasEventMsgEnvelope) }); + new[] {typeof(AdminShellEvents.AasEventMsgEnvelope)}); settings.TypeNameHandling = TypeNameHandling.Auto; settings.Formatting = Formatting.Indented; var json = JsonConvert.SerializeObject(obj, settings); @@ -2742,7 +2846,7 @@ public static void SendJsonResponse(Grapevine.Interfaces.Server.IHttpContext con var length = buffer.Length; var queryString = context.Request.QueryString; - string refresh = queryString["refresh"]; + string refresh = queryString[ "refresh" ]; if (refresh != null && refresh != "") { context.Response.Headers.Remove("Refresh"); @@ -2765,6 +2869,7 @@ public class diffEntry public DateTime timeStamp = new DateTime(); public string value = ""; } + private static void addEntry(bool diffJson, ref string diffText, ref List diffList, string mode = "", string path = "", string type = "", DateTime timeStamp = new DateTime(), string value = "") { @@ -2782,20 +2887,20 @@ private static void addEntry(bool diffJson, ref string diffText, ref List"; - + timeStamp.ToString("yy-MM-dd HH:mm:ss.fff") + ""; } else { diffText += "DELETE" + path + "" + type + "" + - timeStamp.ToString("yy-MM-dd HH:mm:ss.fff") + ""; + timeStamp.ToString("yy-MM-dd HH:mm:ss.fff") + ""; } + break; case "CREATE": case "UPDATE": diffText += "" + mode + "" + path + - "" + type + "" + - timeStamp.ToString("yy-MM-dd HH:mm:ss.fff") + ""; + "" + type + "" + + timeStamp.ToString("yy-MM-dd HH:mm:ss.fff") + ""; if (value != "") diffText += "" + value + ""; diffText += ""; @@ -2824,29 +2929,25 @@ private static void addEntry(bool diffJson, ref string diffText, ref List= 0) { @@ -2934,12 +3041,14 @@ public IHttpContext GetDiff(IHttpContext context) { if (i != 2 && i != 3) { - restPath += "/" + split[i]; + restPath += "/" + split[ i ]; } } } } - catch { } + catch + { + } } } @@ -2952,7 +3061,7 @@ public IHttpContext GetDiff(IHttpContext context) for (int imode = 0; imode < modes.Length; imode++) { - string mode = modes[imode]; + string mode = modes[ imode ]; if (mode == "DELETE") { @@ -2972,7 +3081,7 @@ public IHttpContext GetDiff(IHttpContext context) string path = x.IdShort; while (x.Parent != null && x != x.Parent) { - x = (IReferable)x.Parent; + x = (IReferable) x.Parent; path = x.IdShort + "." + path; } @@ -2984,6 +3093,7 @@ public IHttpContext GetDiff(IHttpContext context) } } } + continue; } @@ -2992,10 +3102,10 @@ public IHttpContext GetDiff(IHttpContext context) if (aasIndex >= 0 && i != aasIndex) continue; - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; if (aas.Submodels != null && aas.Submodels.Count > 0) { DateTime diffTimeStamp = new(); @@ -3008,7 +3118,7 @@ public IHttpContext GetDiff(IHttpContext context) if (searchPath == "" || (p.Length <= searchPathLen && p == searchPath.Substring(0, p.Length))) { addEntry(diffJson, ref diffText, ref diffList, - mode, aas.IdShort, "AAS", aas.TimeStamp); + mode, aas.IdShort, "AAS", aas.TimeStamp); } } } @@ -3027,7 +3137,7 @@ public IHttpContext GetDiff(IHttpContext context) if (searchPath == "" || (p.Length <= searchPathLen && p == searchPath.Substring(0, p.Length))) { addEntry(diffJson, ref diffText, ref diffList, - mode, p, "SM", (DateTime)sm.TimeStamp); + mode, p, "SM", (DateTime) sm.TimeStamp); } } @@ -3075,6 +3185,7 @@ static void checkDiff(bool diffJson, ref string diffText, ref List di if (!(searchPath.Length <= p.Length && searchPath == p.Substring(0, searchPath.Length))) return; } + string value = ""; if (mode != "CREATE") value = sme.ValueAsText(); @@ -3121,7 +3232,7 @@ static void checkDiff(bool diffJson, ref string diffText, ref List di } if ((mode == "CREATE" && sme.TimeStampCreate > minimumDate) || - (mode != "CREATE" && sme.TimeStamp > minimumDate && sme.TimeStamp != sme.TimeStampCreate)) + (mode != "CREATE" && sme.TimeStamp > minimumDate && sme.TimeStamp != sme.TimeStampCreate)) { if (searchPath != "") { @@ -3142,8 +3253,7 @@ static void checkDiff(bool diffJson, ref string diffText, ref List di // get authserver - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/authserver(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/authserver(/|)$") ] public IHttpContext GetAuthserver(IHttpContext context) { var txt = AasxServer.Program.redirectServer; @@ -3157,8 +3267,7 @@ public IHttpContext GetAuthserver(IHttpContext context) } // Basic AAS + Asset - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))(|/core|/complete|/thumbnail|/aasenv|/aasenvjson)(/|)$")] - + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))(|/core|/complete|/thumbnail|/aasenv|/aasenvjson)(/|)$") ] public IHttpContext GetAasAndAsset(IHttpContext context) { if (context.Request.PathInfo.Contains("geteventmessages")) @@ -3171,68 +3280,70 @@ public IHttpContext GetAasAndAsset(IHttpContext context) { if (helper.PathEndsWith(context, "thumbnail")) { - helper.EvalGetAasThumbnail(context, m.Groups[1].ToString()); + helper.EvalGetAasThumbnail(context, m.Groups[ 1 ].ToString()); } - else - if (helper.PathEndsWith(context, "aasenv") || helper.PathEndsWith(context, "aasenvjson")) + else if (helper.PathEndsWith(context, "aasenv") || helper.PathEndsWith(context, "aasenvjson")) { - helper.EvalGetAasEnv(context, m.Groups[1].ToString()); + helper.EvalGetAasEnv(context, m.Groups[ 1 ].ToString()); } else { var complete = helper.PathEndsWith(context, "complete"); - helper.EvalGetAasAndAsset(context, m.Groups[1].ToString(), complete: complete); + helper.EvalGetAasAndAsset(context, m.Groups[ 1 ].ToString(), complete: complete); } } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas(/|)$") ] public IHttpContext PutAas(IHttpContext context) { helper.EvalPutAas(context); return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aasx/server(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aasx/server(/|)$") ] public IHttpContext PutAasxOnServer(IHttpContext context) { helper.EvalPutAasxOnServer(context); return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aasx/filesystem/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aasx/filesystem/([^/]+)(/|)$") ] public IHttpContext PutAasxToFileSystem(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalPutAasxToFilesystem(context, m.Groups[1].ToString()); + helper.EvalPutAasxToFilesystem(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/([^/]+)(/|)$") ] public IHttpContext DeleteAasAndAsset(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalDeleteAasAndAsset(context, m.Groups[1].ToString(), deleteAsset: true); + helper.EvalDeleteAasAndAsset(context, m.Groups[ 1 ].ToString(), deleteAsset: true); } + return context; } // Handles - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/handles/identification(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/handles/identification(/|)$") ] public IHttpContext GetHandlesIdentification(IHttpContext context) { helper.EvalGetHandlesIdentification(context); return context; } - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/handles/identification(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/handles/identification(/|)$") ] public IHttpContext PostHandlesIdentification(IHttpContext context) { helper.EvalPostHandlesIdentification(context); @@ -3241,7 +3352,7 @@ public IHttpContext PostHandlesIdentification(IHttpContext context) // Authenticate - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/authenticateGuest(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/authenticateGuest(/|)$") ] public IHttpContext GetAuthenticate(IHttpContext context) { helper.EvalGetAuthenticateGuest(context); @@ -3250,21 +3361,21 @@ public IHttpContext GetAuthenticate(IHttpContext context) // Authenticate User - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateUser(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateUser(/|)$") ] public IHttpContext PostAuthenticateUser(IHttpContext context) { helper.EvalPostAuthenticateUser(context); return context; } - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateCert1(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateCert1(/|)$") ] public IHttpContext PostAuthenticateCert1(IHttpContext context) { helper.EvalPostAuthenticateCert1(context); return context; } - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateCert2(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/authenticateCert2(/|)$") ] public IHttpContext PostAuthenticateCert2(IHttpContext context) { helper.EvalPostAuthenticateCert2(context); @@ -3273,7 +3384,7 @@ public IHttpContext PostAuthenticateCert2(IHttpContext context) // Server - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/profile(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/profile(/|)$") ] public IHttpContext GetServerProfile(IHttpContext context) { helper.EvalGetServerProfile(context); @@ -3281,8 +3392,8 @@ public IHttpContext GetServerProfile(IHttpContext context) } // OZ - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/listaas(/|)$")] - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/listasset(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/listaas(/|)$") ] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/server/listasset(/|)$") ] public IHttpContext GetServerAASX(IHttpContext context) { if (context.Request.PathInfo.Contains("listasset")) @@ -3293,38 +3404,38 @@ public IHttpContext GetServerAASX(IHttpContext context) { helper.EvalGetListAAS(context); } + return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/assetid/(\d+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/assetid/(\d+)(/|)$") ] public IHttpContext AssetId(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalAssetId(context, Int32.Parse(m.Groups[1].ToString())); + helper.EvalAssetId(context, Int32.Parse(m.Groups[ 1 ].ToString())); } return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasx/(\d+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasx/(\d+)(/|)$") ] public IHttpContext GetAASX(IHttpContext context) { - var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalGetAASX(context, Int32.Parse(m.Groups[1].ToString())); + helper.EvalGetAASX(context, Int32.Parse(m.Groups[ 1 ].ToString())); return context; } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = @"^/server/getaasx/(\d+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = @"^/server/getaasx/(\d+)(/|)$") ] public IHttpContext PutAASX(IHttpContext context) { - var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { @@ -3345,47 +3456,49 @@ public IHttpContext PutAASX(IHttpContext context) else { // here goes the official code - helper.EvalPutAasxReplacePackage(context, m.Groups[1].ToString()); + helper.EvalPutAasxReplacePackage(context, m.Groups[ 1 ].ToString()); } + return context; } + return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasxbyassetid/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasxbyassetid/([^/]+)(/|)$") ] public IHttpContext GetAASX2ByAssetId(IHttpContext context) { helper.EvalGetAasxByAssetId(context); return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasx2/(\d+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getaasx2/(\d+)(/|)$") ] public IHttpContext GetAASX2(IHttpContext context) { - var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalGetAASX2(context, Int32.Parse(m.Groups[1].ToString())); + helper.EvalGetAASX2(context, Int32.Parse(m.Groups[ 1 ].ToString())); return context; } + return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getfile/(\d+)/(([^/]+)/){0,99}([^/]+)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = @"^/server/getfile/(\d+)/(([^/]+)/){0,99}([^/]+)$") ] public IHttpContext GetFile(IHttpContext context) { int index = -1; string path = ""; - string[] split = context.Request.PathInfo.Split(new Char[] { '/' }); - if (split[1].ToLower() == "server" && split[2].ToLower() == "getfile") + string[] split = context.Request.PathInfo.Split(new Char[] {'/'}); + if (split[ 1 ].ToLower() == "server" && split[ 2 ].ToLower() == "getfile") { - index = Int32.Parse(split[3]); + index = Int32.Parse(split[ 3 ]); int i = 4; while (i < split.Length) { - path += "/" + split[i]; + path += "/" + split[ i ]; i++; } } @@ -3397,80 +3510,85 @@ public IHttpContext GetFile(IHttpContext context) // Assets - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/assets/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/assets/([^/]+)(/|)$") ] public IHttpContext GetAssets(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalGetAssetLinks(context, m.Groups[1].ToString()); + helper.EvalGetAssetLinks(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/assets(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/assets(/|)$") ] public IHttpContext PutAssets(IHttpContext context) { helper.EvalPutAsset(context); return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/asset(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/asset(/|)$") ] public IHttpContext PutAssetsToAas(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalPutAssetToAas(context, m.Groups[1].ToString()); + helper.EvalPutAssetToAas(context, m.Groups[ 1 ].ToString()); } + return context; } // List of Submodels - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels(/|)$") ] public IHttpContext GetSubmodels(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalGetSubmodels(context, m.Groups[1].ToString()); + helper.EvalGetSubmodels(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/submodels(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/submodels(/|)$") ] public IHttpContext PutSubmodel(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalPutSubmodel(context, m.Groups[1].ToString()); + helper.EvalPutSubmodel(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)(/|)$") ] public IHttpContext DeleteSubmodel(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 4) { - helper.EvalDeleteSubmodel(context, m.Groups[1].ToString(), m.Groups[3].ToString()); + helper.EvalDeleteSubmodel(context, m.Groups[ 1 ].ToString(), m.Groups[ 3 ].ToString()); } + return context; } // Contents of a Submodel - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)(|/core|/deep|/complete|/values)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)(|/core|/deep|/complete|/values)(/|)$") ] public IHttpContext GetSubmodelContents(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 4) { - var aasid = m.Groups[1].ToString(); - var smid = m.Groups[3].ToString(); + var aasid = m.Groups[ 1 ].ToString(); + var smid = m.Groups[ 3 ].ToString(); if (helper.PathEndsWith(context, "values")) { @@ -3483,52 +3601,54 @@ public IHttpContext GetSubmodelContents(IHttpContext context) helper.EvalGetSubmodelContents(context, aasid, smid, deep: deep || complete, complete: complete); } } + return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/table(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/table(/|)$") ] public IHttpContext GetSubmodelContentsAsTable(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 4) { - helper.EvalGetSubmodelContentsAsTable(context, m.Groups[1].ToString(), m.Groups[3].ToString()); + helper.EvalGetSubmodelContentsAsTable(context, m.Groups[ 1 ].ToString(), m.Groups[ 3 ].ToString()); } + return context; } // Contents of SubmodelElements - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/submodel/submodelElements(/([^/]+)){1,99}?(|/core|/complete|/deep|/file|/blob|/events|/values/value)(/|)$")] // BaSyx-Style - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){1,99}?(|/core|/complete|/deep|/file|/blob|/events|/values|/value)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, + PathInfo = + "^/aas/(id|([^/]+))/submodels/([^/]+)/submodel/submodelElements(/([^/]+)){1,99}?(|/core|/complete|/deep|/file|/blob|/events|/values/value)(/|)$") ] // BaSyx-Style + [ RestRoute(HttpMethod = HttpMethod.GET, + PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){1,99}?(|/core|/complete|/deep|/file|/blob|/events|/values|/value)(/|)$") ] public IHttpContext GetSubmodelElementsContents(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo.Replace("submodel/submodelElements", "elements")); - if (m.Success && m.Groups.Count >= 6 && m.Groups[5].Captures != null && m.Groups[5].Captures.Count >= 1) + if (m.Success && m.Groups.Count >= 6 && m.Groups[ 5 ].Captures != null && m.Groups[ 5 ].Captures.Count >= 1) { - var aasid = m.Groups[1].ToString(); - var smid = m.Groups[3].ToString(); + var aasid = m.Groups[ 1 ].ToString(); + var smid = m.Groups[ 3 ].ToString(); var elemids = new List(); - for (int i = 0; i < m.Groups[5].Captures.Count; i++) - elemids.Add(m.Groups[5].Captures[i].ToString()); + for (int i = 0; i < m.Groups[ 5 ].Captures.Count; i++) + elemids.Add(m.Groups[ 5 ].Captures[ i ].ToString()); // special case?? if (helper.PathEndsWith(context, "file")) { helper.EvalGetSubmodelElementsFile(context, aasid, smid, elemids.ToArray()); } - else - if (helper.PathEndsWith(context, "blob")) + else if (helper.PathEndsWith(context, "blob")) { helper.EvalGetSubmodelElementsBlob(context, aasid, smid, elemids.ToArray()); } - else - if (helper.PathEndsWith(context, "values") || helper.PathEndsWith(context, "value")) + else if (helper.PathEndsWith(context, "values") || helper.PathEndsWith(context, "value")) { helper.EvalGetSubmodelAllElementsProperty(context, aasid, smid, elemids.ToArray()); } - else - if (helper.PathEndsWith(context, "events")) + else if (helper.PathEndsWith(context, "events")) { context.Response.SendResponse(Grapevine.Shared.HttpStatusCode.NotImplemented, $"Events currently not implented."); } @@ -3547,20 +3667,21 @@ public IHttpContext GetSubmodelElementsContents(IHttpContext context) helper.EvalGetSubmodelElementContents(context, aasid, smid, elemids.ToArray(), deep, complete); } } + return context; } - [RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){1,99}?/invoke(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.POST, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){1,99}?/invoke(/|)$") ] public IHttpContext PostSubmodelElementsContents(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); - if (m.Success && m.Groups.Count >= 6 && m.Groups[5].Captures != null && m.Groups[5].Captures.Count >= 1) + if (m.Success && m.Groups.Count >= 6 && m.Groups[ 5 ].Captures != null && m.Groups[ 5 ].Captures.Count >= 1) { - var aasid = m.Groups[1].ToString(); - var smid = m.Groups[3].ToString(); + var aasid = m.Groups[ 1 ].ToString(); + var smid = m.Groups[ 3 ].ToString(); var elemids = new List(); - for (int i = 0; i < m.Groups[5].Captures.Count; i++) - elemids.Add(m.Groups[5].Captures[i].ToString()); + for (int i = 0; i < m.Groups[ 5 ].Captures.Count; i++) + elemids.Add(m.Groups[ 5 ].Captures[ i ].ToString()); // special case?? if (helper.PathEndsWith(context, "invoke")) @@ -3568,29 +3689,31 @@ public IHttpContext PostSubmodelElementsContents(IHttpContext context) helper.EvalInvokeSubmodelElementOperation(context, aasid, smid, elemids.ToArray()); } } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$") ] public IHttpContext PutSubmodelElementsContents(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 6) { - var aasid = m.Groups[1].ToString(); - var smid = m.Groups[3].ToString(); + var aasid = m.Groups[ 1 ].ToString(); + var smid = m.Groups[ 3 ].ToString(); var elemids = new List(); - if (m.Groups[5].Captures != null) - for (int i = 0; i < m.Groups[5].Captures.Count; i++) - elemids.Add(m.Groups[5].Captures[i].ToString()); + if (m.Groups[ 5 ].Captures != null) + for (int i = 0; i < m.Groups[ 5 ].Captures.Count; i++) + elemids.Add(m.Groups[ 5 ].Captures[ i ].ToString()); helper.EvalPutSubmodelElementContents(context, aasid, smid, elemids.ToArray()); } + return context; } //An OPTIONS preflight call is made by browser before calling actual PUT - [RestRoute(HttpMethod = HttpMethod.OPTIONS, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.OPTIONS, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$") ] public IHttpContext OptionsSubmodelElementsContents(IHttpContext context) { SendJsonResponse(context, new Object()); //returning just an empty object @@ -3598,75 +3721,79 @@ public IHttpContext OptionsSubmodelElementsContents(IHttpContext context) } - [RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/submodels/([^/]+)/elements(/([^/]+)){0,99}?(/|)$") ] public IHttpContext DeleteSubmodelElementsContents(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 6) { - var aasid = m.Groups[1].ToString(); - var smid = m.Groups[3].ToString(); + var aasid = m.Groups[ 1 ].ToString(); + var smid = m.Groups[ 3 ].ToString(); var elemids = new List(); - if (m.Groups[5].Captures != null) - for (int i = 0; i < m.Groups[5].Captures.Count; i++) - elemids.Add(m.Groups[5].Captures[i].ToString()); + if (m.Groups[ 5 ].Captures != null) + for (int i = 0; i < m.Groups[ 5 ].Captures.Count; i++) + elemids.Add(m.Groups[ 5 ].Captures[ i ].ToString()); helper.EvalDeleteSubmodelElementContents(context, aasid, smid, elemids.ToArray()); } + return context; } // concept descriptions - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/cds(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/cds(/|)$") ] public IHttpContext GetCds(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalGetAllCds(context, m.Groups[1].ToString()); + helper.EvalGetAllCds(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/cds(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.PUT, PathInfo = "^/aas/(id|([^/]+))/cds(/|)$") ] public IHttpContext PutConceptDescription(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 2) { - helper.EvalPutCd(context, m.Groups[1].ToString()); + helper.EvalPutCd(context, m.Groups[ 1 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/cds/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.GET, PathInfo = "^/aas/(id|([^/]+))/cds/([^/]+)(/|)$") ] public IHttpContext GetSpecificCd(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 4) { - helper.EvalGetCdContents(context, m.Groups[1].ToString(), m.Groups[3].ToString()); + helper.EvalGetCdContents(context, m.Groups[ 1 ].ToString(), m.Groups[ 3 ].ToString()); } + return context; } - [RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/cds/([^/]+)(/|)$")] + [ RestRoute(HttpMethod = HttpMethod.DELETE, PathInfo = "^/aas/(id|([^/]+))/cds/([^/]+)(/|)$") ] public IHttpContext DeleteSpecificCd(IHttpContext context) { var m = helper.PathInfoRegexMatch(MethodBase.GetCurrentMethod(), context.Request.PathInfo); if (m.Success && m.Groups.Count >= 4) { - helper.EvalDeleteSpecificCd(context, m.Groups[1].ToString(), m.Groups[3].ToString()); + helper.EvalDeleteSpecificCd(context, m.Groups[ 1 ].ToString(), m.Groups[ 3 ].ToString()); } + return context; } - } private static RestServer startedRestServer = null; - public static void Start(AdminShellPackageEnv[] packages, string host, string port, bool https, GrapevineLoggerSuper logger = null) + public static void Start(AdminShellPackageEnv[] packages, string host, string port, bool https) { // if running, stop old server Stop(); @@ -3680,23 +3807,10 @@ public static void Start(AdminShellPackageEnv[] packages, string host, string po serverSettings.Port = port; serverSettings.UseHttps = https; - if (logger != null) - logger.Warn("Please notice: the API and REST routes implemented in this version of the source code are not specified and standardised by the" + - "specification Details of the Administration Shell. The hereby stated approach is solely the opinion of its author(s)."); - startedRestServer = new RestServer(serverSettings); - { - if (logger != null) - startedRestServer.Logger = logger; - startedRestServer.Start(); - Console.WriteLine(startedRestServer.ListenerPrefix); - } - - // tail of the messages, again - if (logger != null) - logger.Warn("Please notice: the API and REST routes implemented in this version of the source code are not specified and standardised by the" + - "specification Details of the Administration Shell. The hereby stated approach is solely the opinion of its author(s)."); + startedRestServer.Start(); + Console.WriteLine(startedRestServer.ListenerPrefix); } public static void Stop() @@ -3707,7 +3821,9 @@ public static void Stop() startedRestServer.Stop(); startedRestServer = null; } - catch { } + catch + { + } } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/AasxServerStandardBib.csproj b/src/AasxServerStandardBib/AasxServerStandardBib.csproj index 197db5179..b4d74a859 100644 --- a/src/AasxServerStandardBib/AasxServerStandardBib.csproj +++ b/src/AasxServerStandardBib/AasxServerStandardBib.csproj @@ -1,66 +1,59 @@  - - - net6.0 - en-US;de-DE - ef550880-6a5f-4e0c-b634-8284f1dc5445 - + + + net6.0 + en-US;de-DE + ef550880-6a5f-4e0c-b634-8284f1dc5445 + - - false - + + false + - - TRACE;UseAasxCompatibilityModels - portable - true - - - - + + TRACE;UseAasxCompatibilityModels + portable + true + + + + - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + - - - Always - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - + + + Always + + + + + PreserveNewest + + diff --git a/src/AasxServerStandardBib/AasxUaServerOptions.cs b/src/AasxServerStandardBib/AasxUaServerOptions.cs deleted file mode 100644 index 5520896e5..000000000 --- a/src/AasxServerStandardBib/AasxUaServerOptions.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace AasOpcUaServer -{ - public class AasxUaServerOptions - { - public enum JobType { None, ExportNodesetXml } - - /// - /// This file shall be loaded at start of application - /// - public string AasxToLoad = null; - - /// - /// Set special action/ job to be executed by server - /// - public JobType SpecialJob = JobType.None; - - /// - /// File Name for exporting - /// - public string ExportFilename = ""; - - /// - /// If not Null, the Namespace index of exported nodes need to be in the list. - /// - public List ExportFilterNamespaceIndex = null; - - /// - /// Serialize reference as single string object instead of list of strings. - /// Note: set to TRUE for open62541 node-set-compiler - /// - public bool ReferenceKeysAsSingleString = false; - - /// - /// Filter duplicated node-ids in th export. - /// Note: set to TRUE for open62541 node-set-compiler - /// - public bool FilterForSingleNodeIds = false; - - /// - /// If not null, then executed after finalizing special jobs. Will be set-up during initialization of server. - /// - public Action FinalizeAction = null; - - /// - /// Parse args given by command line or plug-in arguments - /// - public void ParseArgs(string[] args) - { - if (args == null) - return; - - for (int index = 0; index < args.Length; index++) - { - var arg = args[index].Trim().ToLower(); - var morearg = (args.Length - 1) - index; - - // flags - if (arg == "-single-keys") - { - ReferenceKeysAsSingleString = true; - continue; - } - - if (arg == "-single-nodeids") - { - FilterForSingleNodeIds = true; - continue; - } - - // options - if (arg == "-ns" && morearg > 0) - { - int i; - if (Int32.TryParse(args[index + 1], out i)) - { - if (this.ExportFilterNamespaceIndex == null) - this.ExportFilterNamespaceIndex = new List(); - this.ExportFilterNamespaceIndex.Add((ushort)i); - } - index++; - continue; - } - if (arg == "-export-nodeset" && morearg > 0) - { - this.SpecialJob = JobType.ExportNodesetXml; - this.ExportFilename = args[index + 1]; - index++; - continue; - } - - // tail. last argument shall be file to load - if (System.IO.File.Exists(args[index])) - this.AasxToLoad = args[index]; - break; - } - } - } -} diff --git a/src/AasxServerStandardBib/AttributeClasses.cs b/src/AasxServerStandardBib/AttributeClasses.cs deleted file mode 100644 index b49567180..000000000 --- a/src/AasxServerStandardBib/AttributeClasses.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace AasxServerStandardBib -{ - // - // Attributes - // - - /// - /// This attribute indicates, that it should e.g. serialized in JSON. - /// - [System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = true)] - public class CountForHash : System.Attribute - { - } - - /// - /// This attribute indicates, that evaluation shall not count following field or not dive into references. - /// - [System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = true)] - public class SkipForHash : System.Attribute - { - } - - /// - /// This attribute indicates, that the field / property is searchable - /// - [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)] - public class MetaModelName : System.Attribute - { - public string name; - public MetaModelName(string name) - { - this.name = name; - } - } - - /// - /// This attribute indicates, that the field / property shall be skipped for reflection - /// in order to avoid cycles - /// - [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)] - public class SkipForReflection : System.Attribute - { - } - - /// - /// This attribute indicates, that the field / property shall be skipped for searching, because it is not - /// directly displayed in Package Explorer - /// - [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)] - public class SkipForSearch : System.Attribute - { - } - - /// - /// This attribute indicates, that the field / property is searchable - /// - [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)] - public class TextSearchable : System.Attribute - { - } -} diff --git a/src/AasxServerStandardBib/Credentials.cs b/src/AasxServerStandardBib/Credentials.cs index ab5ba14c5..ce2414738 100644 --- a/src/AasxServerStandardBib/Credentials.cs +++ b/src/AasxServerStandardBib/Credentials.cs @@ -72,6 +72,7 @@ public static void initByFile(List cList, string fileName) line = sr.ReadLine(); } } + Console.WriteLine("CREDENTIALS " + fileName + ":" + cList.Count + " entries read"); } catch (IOException e) { @@ -120,7 +121,7 @@ public static void initByEdc(List cList, string user, stri } public static bool get(List cList, string urlPath, out string queryPara, out string userPW, - out string urlEdcWrapper, out string replace) + out string urlEdcWrapper, out string replace, bool blazor = false) { queryPara = ""; userPW = ""; @@ -188,9 +189,12 @@ public static bool get(List cList, string urlPath, out str result = true; break; case "replace": - if (cList[i].parameters.Count == 1) + if (cList[i].parameters.Count == 1 || + (cList[i].parameters.Count == 2 && cList[i].parameters[1] == "blazor" && blazor)) + { replace = urlPath.Replace(u, cList[i].parameters[0]); - result = true; + result = true; + } break; } } diff --git a/src/AasxServerStandardBib/DataChangeMonitoredItem.cs b/src/AasxServerStandardBib/DataChangeMonitoredItem.cs deleted file mode 100644 index 8859653f2..000000000 --- a/src/AasxServerStandardBib/DataChangeMonitoredItem.cs +++ /dev/null @@ -1,826 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Text; -using Opc.Ua.Server; - -namespace Opc.Ua.Sample -{ - /// - /// Provides a basic monitored item implementation which does not support queuing. - /// - public class DataChangeMonitoredItem : IDataChangeMonitoredItem - { - #region Constructors - /// - /// Constructs a new instance. - /// - public DataChangeMonitoredItem( - MonitoredNode source, - uint id, - uint attributeId, - NumericRange indexRange, - QualifiedName dataEncoding, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - MonitoringMode monitoringMode, - uint clientHandle, - double samplingInterval, - bool alwaysReportUpdates) - { - m_source = source; - m_id = id; - m_attributeId = attributeId; - m_indexRange = indexRange; - m_dataEncoding = dataEncoding; - m_timestampsToReturn = timestampsToReturn; - m_diagnosticsMasks = diagnosticsMasks; - m_monitoringMode = monitoringMode; - m_clientHandle = clientHandle; - m_samplingInterval = samplingInterval; - m_nextSampleTime = DateTime.UtcNow.Ticks; - m_readyToPublish = false; - m_readyToTrigger = false; - m_alwaysReportUpdates = alwaysReportUpdates; - } - - /// - /// Constructs a new instance. - /// - public DataChangeMonitoredItem( - MonitoredNode source, - uint id, - uint attributeId, - NumericRange indexRange, - QualifiedName dataEncoding, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - MonitoringMode monitoringMode, - uint clientHandle, - double samplingInterval, - uint queueSize, - bool discardOldest, - DataChangeFilter filter, - Range range, - bool alwaysReportUpdates) - { - m_source = source; - m_id = id; - m_attributeId = attributeId; - m_indexRange = indexRange; - m_dataEncoding = dataEncoding; - m_timestampsToReturn = timestampsToReturn; - m_diagnosticsMasks = diagnosticsMasks; - m_monitoringMode = monitoringMode; - m_clientHandle = clientHandle; - m_samplingInterval = samplingInterval; - m_nextSampleTime = DateTime.UtcNow.Ticks; - m_readyToPublish = false; - m_readyToTrigger = false; - m_queue = null; - m_filter = filter; - m_range = 0; - m_alwaysReportUpdates = alwaysReportUpdates; - - if (range != null) - { - m_range = range.High - range.Low; - } - - if (queueSize > 1) - { - m_queue = new MonitoredItemQueue(); - m_queue.SetQueueSize(queueSize, discardOldest, diagnosticsMasks); - m_queue.SetSamplingInterval(samplingInterval); - } - } - #endregion - - #region Public Members - /// - /// Gets the id for the attribute being monitored. - /// - public uint AttributeId - { - get { return m_attributeId; } - } - - /// - /// Gets the index range used to selected a subset of the value. - /// - public NumericRange IndexRange - { - get { return m_indexRange; } - } - - /// - /// Gets the data encoding to use when returning the value. - /// - public QualifiedName DataEncoding - { - get { return m_dataEncoding; } - } - - /// - /// Whether the monitored item should report a value without checking if it was changed. - /// - public bool AlwaysReportUpdates - { - get { return m_alwaysReportUpdates; } - set { m_alwaysReportUpdates = value; } - } - - /// - /// The number of milliseconds until the next sample. - /// - public int TimeToNextSample - { - get - { - lock (m_lock) - { - if (m_monitoringMode == MonitoringMode.Disabled) - { - return Int32.MaxValue; - } - - DateTime now = DateTime.UtcNow; - - if (m_nextSampleTime <= now.Ticks) - { - return 0; - } - - return (int)((m_nextSampleTime - now.Ticks) / TimeSpan.TicksPerMillisecond); - } - } - } - - /// - /// The monitoring mode. - /// - public MonitoringMode MonitoringMode - { - get - { - return m_monitoringMode; - } - } - - /// - /// The sampling interval. - /// - public double SamplingInterval - { - get - { - lock (m_lock) - { - return m_samplingInterval; - } - } - } - - /// - /// Modifies the monitored item parameters, - /// - public ServiceResult Modify( - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - uint clientHandle, - double samplingInterval) - { - return Modify(diagnosticsMasks, timestampsToReturn, clientHandle, samplingInterval, 0, false, null, null); - } - - /// - /// Modifies the monitored item parameters, - /// - public ServiceResult Modify( - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - uint clientHandle, - double samplingInterval, - uint queueSize, - bool discardOldest, - DataChangeFilter filter, - Range range) - { - lock (m_lock) - { - m_diagnosticsMasks = diagnosticsMasks; - m_timestampsToReturn = timestampsToReturn; - m_clientHandle = clientHandle; - - // subtract the previous sampling interval. - long oldSamplingInterval = (long)(m_samplingInterval * TimeSpan.TicksPerMillisecond); - - if (oldSamplingInterval < m_nextSampleTime) - { - m_nextSampleTime -= oldSamplingInterval; - } - - m_samplingInterval = samplingInterval; - - // calculate the next sampling interval. - long newSamplingInterval = (long)(m_samplingInterval * TimeSpan.TicksPerMillisecond); - - if (m_samplingInterval > 0) - { - m_nextSampleTime += newSamplingInterval; - } - else - { - m_nextSampleTime = 0; - } - - // update the filter and the range. - m_filter = filter; - m_range = 0; - - if (range != null) - { - m_range = range.High - range.Low; - } - - // update the queue size. - if (queueSize > 1) - { - if (m_queue == null) - { - m_queue = new MonitoredItemQueue(); - } - - m_queue.SetQueueSize(queueSize, discardOldest, diagnosticsMasks); - m_queue.SetSamplingInterval(samplingInterval); - } - else - { - m_queue = null; - } - - return ServiceResult.Good; - } - } - - /// - /// Called when the attribute being monitored changed. Reads and queues the value. - /// - public void ValueChanged(ISystemContext context) - { - DataValue value = new DataValue(); - - ServiceResult error = m_source.Node.ReadAttribute(context, m_attributeId, NumericRange.Empty, null, value); - - if (ServiceResult.IsBad(error)) - { - value = new DataValue(error.StatusCode); - } - - value.ServerTimestamp = DateTime.UtcNow; - - QueueValue(value, error); - } - #endregion - - #region IMonitoredItem Members - /// - /// The node manager for the monitored item. - /// - public INodeManager NodeManager - { - get { return m_source.NodeManager; } - } - - /// - /// The session for the monitored item. - /// - public Session Session - { - get - { - ISubscription subscription = m_subscription; - - if (subscription != null) - { - return subscription.Session; - } - - return null; - } - } - - /// - /// The identifier for the subscription that the monitored item belongs to. - /// - public uint SubscriptionId - { - get - { - ISubscription subscription = m_subscription; - - if (subscription != null) - { - return subscription.Id; - } - - return 0; - } - } - - /// - /// The unique identifier for the monitored item. - /// - public uint Id - { - get { return m_id; } - } - - /// - /// The client handle. - /// - public uint ClientHandle - { - get { return m_clientHandle; } - } - - /// - /// The callback to use to notify the subscription when values are ready to publish. - /// - public ISubscription SubscriptionCallback - { - get - { - return m_subscription; - } - - set - { - m_subscription = value; - } - } - - /// - /// The handle assigned to the monitored item by the node manager. - /// - public object ManagerHandle - { - get { return m_source; } - } - - /// - /// The type of monitor item. - /// - public int MonitoredItemType - { - get { return MonitoredItemTypeMask.DataChange; } - } - - /// - /// Returns true if the item is ready to publish. - /// - public bool IsReadyToPublish - { - get - { - lock (m_lock) - { - // check if not ready to publish. - if (!m_readyToPublish) - { - return false; - } - - // check if monitoring was turned off. - if (m_monitoringMode != MonitoringMode.Reporting) - { - return false; - } - - // re-queue if too little time has passed since the last publish. - long now = DateTime.UtcNow.Ticks; - - if (m_nextSampleTime > now) - { - return false; - } - - return true; - } - } - } - - /// - /// Gets or Sets a value indicating whether the item is ready to trigger in case it has some linked items. - /// - public bool IsReadyToTrigger - { - get - { - lock (m_lock) - { - // only allow to trigger if sampling or reporting. - if (m_monitoringMode == MonitoringMode.Disabled) - { - return false; - } - - return m_readyToTrigger; - } - } - - set - { - lock (m_lock) - { - m_readyToTrigger = value; - } - } - } - - /// - /// Returns the results for the create request. - /// - public ServiceResult GetCreateResult(out MonitoredItemCreateResult result) - { - lock (m_lock) - { - result = new MonitoredItemCreateResult(); - - result.MonitoredItemId = m_id; - result.StatusCode = StatusCodes.Good; - result.RevisedSamplingInterval = m_samplingInterval; - result.RevisedQueueSize = 0; - result.FilterResult = null; - - if (m_queue != null) - { - result.RevisedQueueSize = m_queue.QueueSize; - } - - return ServiceResult.Good; - } - } - - /// - /// Returns the results for the modify request. - /// - public ServiceResult GetModifyResult(out MonitoredItemModifyResult result) - { - lock (m_lock) - { - result = new MonitoredItemModifyResult(); - - result.StatusCode = StatusCodes.Good; - result.RevisedSamplingInterval = m_samplingInterval; - result.RevisedQueueSize = 0; - result.FilterResult = null; - - if (m_queue != null) - { - result.RevisedQueueSize = m_queue.QueueSize; - } - - return ServiceResult.Good; - } - } - #endregion - - #region IDataChangeMonitoredItem Members - /// - /// Queues a new data change. - /// - public void QueueValue(DataValue value, ServiceResult error) - { - lock (m_lock) - { - // check if value has changed. - if (!m_alwaysReportUpdates) - { - if (!Opc.Ua.Server.MonitoredItem.ValueChanged(value, error, m_lastValue, m_lastError, m_filter, m_range)) - { - return; - } - } - - // make a shallow copy of the value. - if (value != null) - { - DataValue copy = new DataValue(); - - copy.WrappedValue = value.WrappedValue; - copy.StatusCode = value.StatusCode; - copy.SourceTimestamp = value.SourceTimestamp; - copy.SourcePicoseconds = value.SourcePicoseconds; - copy.ServerTimestamp = value.ServerTimestamp; - copy.ServerPicoseconds = value.ServerPicoseconds; - - value = copy; - - // ensure the data value matches the error status code. - if (error != null && error.StatusCode.Code != 0) - { - value.StatusCode = error.StatusCode; - } - } - - m_lastValue = value; - m_lastError = error; - - // queue value. - if (m_queue != null) - { - m_queue.QueueValue(value, error); - } - - // flag the item as ready to publish. - m_readyToPublish = true; - m_readyToTrigger = true; - } - } - - /// - /// Sets a flag indicating that the semantics for the monitored node have changed. - /// - /// - /// The StatusCode for next value reported by the monitored item will have the SemanticsChanged bit set. - /// - public void SetSemanticsChanged() - { - lock (m_lock) - { - m_semanticsChanged = true; - } - } - - /// - /// Sets a flag indicating that the structure of the monitored node has changed. - /// - /// - /// The StatusCode for next value reported by the monitored item will have the StructureChanged bit set. - /// - public void SetStructureChanged() - { - lock (m_lock) - { - m_structureChanged = true; - } - } - - /// - /// Changes the monitoring mode. - /// - public MonitoringMode SetMonitoringMode(MonitoringMode monitoringMode) - { - lock (m_lock) - { - MonitoringMode previousMode = m_monitoringMode; - - if (previousMode == monitoringMode) - { - return previousMode; - } - - if (previousMode == MonitoringMode.Disabled) - { - m_nextSampleTime = DateTime.UtcNow.Ticks; - m_lastError = null; - m_lastValue = null; - } - - m_monitoringMode = monitoringMode; - - if (monitoringMode == MonitoringMode.Disabled) - { - m_readyToPublish = false; - m_readyToTrigger = false; - } - - return previousMode; - } - } - - /// - /// No filters supported. - /// - public DataChangeFilter DataChangeFilter - { - get { return m_filter; } - } - - public bool IsResendData => throw new NotImplementedException(); - - /// - /// Increments the sample time to the next interval. - /// - private void IncrementSampleTime() - { - // update next sample time. - long now = DateTime.UtcNow.Ticks; - long samplingInterval = (long)(m_samplingInterval * TimeSpan.TicksPerMillisecond); - - if (m_nextSampleTime > 0) - { - long delta = now - m_nextSampleTime; - - if (samplingInterval > 0 && delta >= 0) - { - m_nextSampleTime += ((delta / samplingInterval) + 1) * samplingInterval; - } - } - - // set sampling time based on current time. - else - { - m_nextSampleTime = now + samplingInterval; - } - } - - /// - /// Called by the subscription to publish any notification. - /// - public bool Publish(OperationContext context, Queue notifications, Queue diagnostics) - { - lock (m_lock) - { - // check if not ready to publish. - if (!IsReadyToPublish) - { - return false; - } - - // update sample time. - IncrementSampleTime(); - - // update publish flag. - m_readyToPublish = false; - m_readyToTrigger = false; - - // check if queuing is enabled. - if (m_queue == null) - { - Publish(context, m_lastValue, m_lastError, notifications, diagnostics); - } - else - { - DataValue value = null; - ServiceResult error = null; - - while (m_queue.Publish(out value, out error)) - { - Publish(context, value, error, notifications, diagnostics); - } - } - - return true; - } - } - - /// - /// Publishes a value. - /// - private void Publish( - OperationContext context, - DataValue value, - ServiceResult error, - Queue notifications, - Queue diagnostics) - { - // set semantics changed bit. - if (m_semanticsChanged) - { - if (value != null) - { - value.StatusCode = value.StatusCode.SetSemanticsChanged(true); - } - - if (error != null) - { - error = new ServiceResult( - error.StatusCode.SetSemanticsChanged(true), - error.SymbolicId, - error.NamespaceUri, - error.LocalizedText, - error.AdditionalInfo, - error.InnerResult); - } - - m_semanticsChanged = false; - } - - // set structure changed bit. - if (m_structureChanged) - { - if (value != null) - { - value.StatusCode = value.StatusCode.SetStructureChanged(true); - } - - if (error != null) - { - error = new ServiceResult( - error.StatusCode.SetStructureChanged(true), - error.SymbolicId, - error.NamespaceUri, - error.LocalizedText, - error.AdditionalInfo, - error.InnerResult); - } - - m_structureChanged = false; - } - - // copy data value. - MonitoredItemNotification item = new MonitoredItemNotification(); - - item.ClientHandle = m_clientHandle; - item.Value = value; - - // apply timestamp filter. - if (m_timestampsToReturn != TimestampsToReturn.Server && m_timestampsToReturn != TimestampsToReturn.Both) - { - item.Value.ServerTimestamp = DateTime.MinValue; - } - - if (m_timestampsToReturn != TimestampsToReturn.Source && m_timestampsToReturn != TimestampsToReturn.Both) - { - item.Value.SourceTimestamp = DateTime.MinValue; - } - - notifications.Enqueue(item); - - // update diagnostic info. - DiagnosticInfo diagnosticInfo = null; - - if (m_lastError != null) - { - if ((m_diagnosticsMasks & DiagnosticsMasks.OperationAll) != 0) - { - diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_source.Server, context, m_lastError); - } - } - - diagnostics.Enqueue(diagnosticInfo); - } - - public void SetupResendDataTrigger() - { - throw new NotImplementedException(); - } - #endregion - - #region Private Fields - private object m_lock = new object(); - private MonitoredNode m_source; - private ISubscription m_subscription; - private uint m_id; - private DataValue m_lastValue; - private ServiceResult m_lastError; - private uint m_attributeId; - private NumericRange m_indexRange; - private QualifiedName m_dataEncoding; - private TimestampsToReturn m_timestampsToReturn; - private DiagnosticsMasks m_diagnosticsMasks; - private uint m_clientHandle; - private double m_samplingInterval; - private MonitoredItemQueue m_queue; - private DataChangeFilter m_filter; - private double m_range; - private MonitoringMode m_monitoringMode; - private long m_nextSampleTime; - private bool m_readyToPublish; - private bool m_readyToTrigger; - private bool m_alwaysReportUpdates; - private bool m_semanticsChanged; - private bool m_structureChanged; - #endregion - } -} diff --git a/src/AasxServerStandardBib/EnergyModel.cs b/src/AasxServerStandardBib/EnergyModel.cs deleted file mode 100644 index 9888c5159..000000000 --- a/src/AasxServerStandardBib/EnergyModel.cs +++ /dev/null @@ -1,881 +0,0 @@ - -using AasxTimeSeries; -using Extensions; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading; - -namespace AasxDemonstration -{ - /// - /// This class holds information and provides functions to "automate" the energy model - /// used by the CESMII / LNI4.0 demonstrator. - /// It consists of Properties, which shall be synchronized with Azure IoTHub. It - /// includes a time series (according the SM template spec) as well. - /// - public static class EnergyModel - { - /// - /// Associated class can release trigger events - /// - public interface ITrackHasTrigger - { - bool IsTrigger(SourceSystemBase sosy); - } - - /// - /// Associated class provides a data vlue - /// - public interface ITrackHasValue - { - double GetValue(SourceSystemBase sosy); - } - - /// - /// Associated class renders a value blob according to the time series spec - /// - public interface ITrackRenderValueBlob - { - string RenderValueBlob(SourceSystemBase sosy, int totalSamples); - } - - /// - /// Base class for the source system and its context. Can be used to transport - /// context and global status data w.r.t to the online connect to a source system - /// - public class SourceSystemBase - { - - public static SourceSystemBase FactoryNewSystem( - string sourceType, - string sourceAddress, - string user, string password, - string credentials) - { - // init - sourceType = ("" + sourceType).Trim().ToLower(); - - // debug? - if (sourceType == "debug") - return new SourceSystemDebug(); - - // debug? - if (sourceType == "azure-iothub") - return new SourceSystemAzureHub(sourceAddress, user, password, credentials); - - // no, default - return new SourceSystemBase(); - } - } - - /// - /// Implements a source system, which provides random values to random times - /// - public class SourceSystemDebug : SourceSystemBase - { - public Random Rnd = new Random(); - } - - /// - /// Implements a source system, which gets data from Azure IoTHub - /// - public class SourceSystemAzureHub : SourceSystemBase - { - public SourceSystemAzureHub() : base() { } - - public SourceSystemAzureHub( - string sourceAddress, - string user, string password, - string credentials) : base() - { - // TODO ERICH - } - } - - /// - /// Tracking of a single data point, which is may be online connected to simulation or Azure .. - /// - public class TrackInstanceDataPoint : ITrackHasTrigger, ITrackHasValue - { - /// - /// Link to an EXISTING SME in the associated Submodel instance - /// - public ISubmodelElement Sme; - - /// - /// Link to the online source, e.g. Azure IoTHub - /// - public string SourceId; - - /// - /// Evaluates, if the trigger condition is met, where new data exists - /// - public bool IsTrigger(SourceSystemBase sosy) - { - if (sosy is SourceSystemDebug dbg) - return dbg.Rnd.Next(0, 9) >= 8; - - if (sosy is SourceSystemAzureHub azure) - // TODO ERICH - return false; - - return false; - } - - /// - /// depending on a trigger, gets the actual value - /// - public double GetValue(SourceSystemBase sosy) - { - if (sosy is SourceSystemDebug dbg) - return dbg.Rnd.NextDouble() * 99.9; - - if (sosy is SourceSystemAzureHub azure) - // TODO ERICH - return 0.0; - - return 0.0; - } - } - - private static T AddToSMC( - DateTime timestamp, - SubmodelElementCollection parent, - string idShort, - string semanticIdKey, - string smeValue = null) where T : ISubmodelElement - { - //var newElem = SubmodelElementWrapper.CreateAdequateType(typeof(T)); - var newElem = CreateSubmodelElementInstance(typeof(T)); - - newElem.IdShort = idShort; - newElem.SemanticId = new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, semanticIdKey) }); - newElem.SetTimeStamp(timestamp); - newElem.TimeStampCreate = timestamp; - if (parent?.Value != null) - { - parent.Value.Add(newElem); - parent.SetTimeStamp(timestamp); - } - if (smeValue != null && newElem is Property newP) - newP.Value = smeValue; - if (smeValue != null && newElem is Blob newB) - newB.Value = Encoding.ASCII.GetBytes(smeValue); - return (T)newElem; - } - - private static ISubmodelElement CreateSubmodelElementInstance(Type type) - { - if (type == null || !type.IsSubclassOf(typeof(ISubmodelElement))) - return null; - var sme = Activator.CreateInstance(type) as ISubmodelElement; - return sme; - } - - private static void CopySmeFeatures( - ISubmodelElement dst, ISubmodelElement src, - bool copyIdShort = false, - bool copyDescription = false, - bool copySemanticId = false, - bool copyQualifers = false) - { - // access - if (dst == null || src == null) - return; - - // feature wise - if (copyIdShort) - dst.IdShort = src.IdShort; - - if (copyDescription) - dst.Description = src.Description; - - if (copySemanticId) - dst.SemanticId = src.SemanticId; - - if (copyQualifers) - { - //dst.Qualifiers = new QualifierCollection(); - dst.Qualifiers = new List(); - foreach (var q in src.Qualifiers) - dst.Qualifiers.Add(q); - } - } - - private static void UpdateSME( - ISubmodelElement sme, - string value, - DateTime timestamp) - { - // update - if (sme is Property prop) - { - prop.Value = value; - } - if (sme is Blob blob) - { - blob.Value = Encoding.ASCII.GetBytes(value); - } - - // time stamping - sme.SetTimeStamp(timestamp); - } - - /// - /// Tracking of a single time series variable; in accordance to a time axis (trigger) - /// multiple values will aggregated - /// - public class TrackInstanceTimeSeriesVariable : ITrackHasValue, ITrackRenderValueBlob - { - /// - /// Link to the CURRENTLY MAINTAINED time series variable in the associated time series segment - /// - public SubmodelElementCollection VariableSmc; - - /// - /// Link to the CURRENTLY MAINTAINED ValueArray in the associated time series segment - /// - public Blob ValueArray; - - /// - /// Link to the online source, e.g. Azure IoTHub - /// - public string SourceId; - - /// - /// Record ID given by the template - /// - public string TemplateRecordId; - - /// - /// Links to respective SME from the providing time series segment TEMPLATE in the originally - /// loaded AASX. - /// - public Property TemplateDataPoint; - - /// - /// Links to respective SMC for the variable from the providing time series segment TEMPLATE in the originally - /// loaded AASX. - /// - public SubmodelElementCollection TemplateVariable; - - /// - /// Maintains the list of values already stored in the variable. - /// Is used to always be able to render a current state of the ValueArray - /// - public List Values = new List(); - - /// - /// Reset the values, clear the runtime associations - /// - public void ClearRuntime() - { - VariableSmc = null; - Values.Clear(); - } - - /// - /// depending on a trigger, gets the actual value - /// - public double GetValue(SourceSystemBase sosy) - { - if (sosy is SourceSystemDebug dbg) - return dbg.Rnd.NextDouble() * 99.9; - - if (sosy is SourceSystemAzureHub azure) - // TODO ERICH - return 0.0; - - return 0.0; - } - - /// - /// Renders list of time stamps according to time series spec - /// - public string RenderValueBlob(SourceSystemBase sosy, int totalSamples) - { - // access - if (Values == null) - return ""; - - // build - return string.Join(", ", Values.Select( - v => String.Format(CultureInfo.InvariantCulture, "[{0}, {1}]", totalSamples++, v) - )); - } - - /// - /// Create a new set of SubmodelElements for the segment. - /// The SegmentSmc and ValueArray will be updated! - /// - public void CreateVariableSmc( - SourceSystemBase sosy, - SubmodelElementCollection segmentSmc, - int totalSamples, - DateTime timeStamp) - { - VariableSmc = AddToSMC( - timeStamp, segmentSmc, - "TSvariable_" + TemplateRecordId, - semanticIdKey: PrefTimeSeries10.CD_TimeSeriesVariable.Value); - - CopySmeFeatures(VariableSmc, TemplateVariable, - copyDescription: true, copyQualifers: true); - - AddToSMC(timeStamp, VariableSmc, - "RecordId", semanticIdKey: PrefTimeSeries10.CD_RecordId.Value, - smeValue: "" + TemplateRecordId); - - var p = AddToSMC(timeStamp, VariableSmc, - "" + TemplateDataPoint?.IdShort, semanticIdKey: null); - - CopySmeFeatures(p, TemplateDataPoint, - copySemanticId: true, copyDescription: true, copyQualifers: true); - - ValueArray = AddToSMC(timeStamp, VariableSmc, - "ValueArray", semanticIdKey: PrefTimeSeries10.CD_ValueArray.Value, - smeValue: RenderValueBlob(sosy, totalSamples)); - } - - /// - /// Updates the currently tracked set of SubmodelElements for the segment. - /// - public void UpdateVariableSmc( - SourceSystemBase sosy, - int totalSamples, - DateTime timeStamp) - { - // access - if (ValueArray == null) - return; - - // render - UpdateSME( - ValueArray, - RenderValueBlob(sosy, totalSamples), - timeStamp); - } - } - - /// - /// Tracking of a time series segement; if values of the time series - /// - public class TrackInstanceTimeSeriesSegment : ITrackHasTrigger, ITrackRenderValueBlob - { - /// - /// Link to the CURRENTLY MAINTAINED time series segment in the associated time series - /// - public SubmodelElementCollection SegmentSmc; - - /// - /// Link to the CURRENTLY MAINTAINED ValueArray for the timestamps in the associated time series segment - /// - public Blob ValueArray; - - /// - /// List of variables to always by MAINTAINED in the segment - /// - public List Variables = new List(); - - /// - /// Holds the timestamp of the samples currently represented in the different variables. - /// This list's length should equal the length of the variable's value lists - /// Note: obviously this means, that this code can only represent time series segments with - /// exactly one time axis. - /// - public List TimeStamps = new List(); - - /// - /// Evaluates, if the trigger condition is met, where new data exists - /// - public bool IsTrigger(SourceSystemBase sosy) - { - if (sosy is SourceSystemDebug dbg) - return dbg.Rnd.Next(0, 9) >= 8; - - if (sosy is SourceSystemAzureHub azure) - // TODO ERICH - return false; - - return false; - } - - /// - /// Reset the values, clear the runtime associations - /// - public void ClearRuntime() - { - SegmentSmc = null; - TimeStamps.Clear(); - foreach (var vr in Variables) - vr.ClearRuntime(); - } - - /// - /// Renders list of time stamps according to time series spec - /// - public string RenderValueBlob(SourceSystemBase sosy, int totalSamples) - { - // access - if (TimeStamps == null) - return ""; - - // build - return string.Join(", ", TimeStamps.Select( - dt => String.Format( - CultureInfo.InvariantCulture, "[{0}, {1}]", - totalSamples++, dt.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")) - )); - } - - /// - /// Create a new set of SubmodelElements for the segment. - /// The SegmentSmc and ValueArray will be updated! - /// - public SubmodelElementCollection CreateSegmentSmc( - SourceSystemBase sosy, - SubmodelElementCollection root, - int segmentIndex, - int totalSamples, - DateTime timeStamp) - { - // segment ifself - SegmentSmc = AddToSMC( - timeStamp, root, - "Segment_" + segmentIndex, - semanticIdKey: PrefTimeSeries10.CD_TimeSeriesSegment.Value); - - // timestamp variables - - var smcVarTS = AddToSMC( - timeStamp, SegmentSmc, - "TSvariable_timeStamp", semanticIdKey: PrefTimeSeries10.CD_TimeSeriesVariable.Value); - - AddToSMC(timeStamp, smcVarTS, - "RecordId", semanticIdKey: PrefTimeSeries10.CD_RecordId.Value, - smeValue: "timeStamp"); - - AddToSMC(timeStamp, smcVarTS, - "UtcTime", semanticIdKey: PrefTimeSeries10.CD_UtcTime.Value); - - ValueArray = AddToSMC(timeStamp, smcVarTS, - "timeStamp", semanticIdKey: PrefTimeSeries10.CD_ValueArray.Value, - smeValue: RenderValueBlob(sosy, totalSamples)); - - // the rest of the variables - - foreach (var vr in Variables) - vr.CreateVariableSmc(sosy, SegmentSmc, totalSamples, timeStamp); - - // ok - return SegmentSmc; - } - - /// - /// Updates the currently tracked set of SubmodelElements for the segment. - /// - public void UpdateSegmentSmc( - SourceSystemBase sosy, - int totalSamples, - DateTime timeStamp) - { - // access - if (ValueArray == null) - return; - - // render - UpdateSME( - ValueArray, - RenderValueBlob(sosy, totalSamples), - timeStamp); - - // the rest of the variables - - foreach (var vr in Variables) - vr.UpdateVariableSmc(sosy, totalSamples, timeStamp); - } - } - - public class EnergyModelInstance - { - // - // Overall Submodel instance - // - - protected ISubmodel _submodel; - - // - // Managing of the actual value propertes - // - - protected List _dataPoint = new List(); - - // - // The following entities serve as directs points to the found instance - // of the energy model. Taken over from TimeSeries.cs - // - - protected SubmodelElementCollection _block, _data; - - protected Property - sampleStatus, sampleMode, sampleRate, lowDataIndex, highDataIndex, - actualSamples, actualSamplesInCollection, - actualCollections; - - protected int - maxSamples = 200, maxSamplesInCollection = 20; - - protected TimeSeriesDestFormat destFormat; - - protected SourceSystemBase _sourceSystem = null; - - protected TrackInstanceTimeSeriesSegment _trackSegment = null; - - protected List _existingSegements - = new List(); - - protected int threadCounter = 0; - protected int samplesCollectionsCount = 0; - protected List samplesProperties = null; - protected List samplesValues = null; - protected string samplesTimeStamp = ""; - protected int samplesValuesCount = 0; - protected int totalSamples = 0; - - // - // Initialize - // - - protected void ScanSubmodelForIoTDataPoints(ISubmodel sm) - { - // access - if (sm == null) - return; - _dataPoint = new List(); - - // find all elements with required qualifier - sm.RecurseOnSubmodelElements(null, (o, parents, sme) => - { - var q = sme.FindQualifierOfType(PrefEnergyModel10.QualiIoTHubDataPoint); - if (q != null && q.Value != null && q.Value.Length > 0) - _dataPoint.Add(new TrackInstanceDataPoint() - { - Sme = sme, - SourceId = q.Value - }); - - //TODO:JT: Need to check again - return true; - }); - } - - /// - /// In Andreas' original code, all AAS and SM need to be tagged for time stamping - /// - public static void TagAllAasAndSm( - AasCore.Aas3_0.Environment env, - DateTime timeStamp) - { - if (env == null) - return; - foreach (var x in env.FindAllSubmodelsGroupedByAAS((aas, sm) => - { - // mark aas - aas.TimeStampCreate = timeStamp; - aas.SetTimeStamp(timeStamp); - - // mark sm - sm.TimeStampCreate = timeStamp; - sm.SetAllParents(timeStamp); - - // need no results - return false; - })) ; - } - - public static IEnumerable FindAllSmInstances( - AasCore.Aas3_0.Environment env) - { - if (env == null) - yield break; - - foreach (var sm in env.FindAllSubmodelBySemanticId( - //SemanticId.CreateFromKey(PrefEnergyModel10.SM_EnergyModel).GetAsIdentifier(), AdminShell.Key.MatchMode.Relaxed)) - PrefEnergyModel10.SM_EnergyModel.Value)) - { - var emi = new EnergyModelInstance(); - emi.ScanSubmodelForIoTDataPoints(sm); - emi.ScanSubmodelForTimeSeriesParameters(sm); - yield return emi; - } - } - - protected void ScanSubmodelForTimeSeriesParameters(ISubmodel sm) - { - // access - if (sm?.SubmodelElements == null) - return; - //var mm = AdminShell.Key.MatchMode.Relaxed; - int i; - - // track of SM - _submodel = sm; - - // find time series models in SM - var smctsCollection = sm.SubmodelElements.FindAllSemanticIdAs(PrefTimeSeries10.CD_TimeSeries.Value); - foreach (var smcts in smctsCollection) - { - // access - if (smcts?.Value == null) - continue; - - // basic SMC references - _block = smcts; - _data = smcts; - - var d2 = smcts.FindFirstIdShortAs("data"); - if (d2 != null) - _data = d2; - - // initialize the source system - - _sourceSystem = SourceSystemBase.FactoryNewSystem( - "" + smcts.FindFirstIdShortAs("sourceType")?.Value, - "" + smcts.FindFirstIdShortAs("sourceAddress")?.Value, - "" + smcts.FindFirstIdShortAs("user")?.Value, - "" + smcts.FindFirstIdShortAs("password")?.Value, - "" + smcts.FindFirstIdShortAs("credentials")?.Value - ); - - // rest of the necessary properties - - sampleStatus = smcts.FindFirstIdShortAs("sampleStatus"); - sampleMode = smcts.FindFirstIdShortAs("sampleMode"); - sampleRate = smcts.FindFirstIdShortAs("sampleRate"); - if (int.TryParse(sampleRate?.Value, out i)) - threadCounter = i; - - if (int.TryParse(smcts.FindFirstIdShortAs("maxSamples")?.Value, out i)) - maxSamples = i; - - if (int.TryParse(smcts.FindFirstIdShortAs("maxSamplesInCollection")?.Value, out i)) - maxSamplesInCollection = i; - - actualSamples = smcts.FindFirstIdShortAs("actualSamples"); - if (actualSamples != null) - actualSamples.Value = "0"; - - actualSamplesInCollection = smcts.FindFirstIdShortAs("actualSamplesInCollection"); - if (actualSamplesInCollection != null) - actualSamplesInCollection.Value = "0"; - - actualCollections = smcts.FindFirstIdShortAs("actualCollections"); - if (actualCollections != null) - actualCollections.Value = "0"; - - lowDataIndex = smcts.FindFirstIdShortAs("lowDataIndex"); - highDataIndex = smcts.FindFirstIdShortAs("highDataIndex"); - - // challenge is to select SMes, which are NOT from a known semantic id! - var tsvAllowed = new[] - { - PrefTimeSeries10.CD_RecordId.Value, - PrefTimeSeries10.CD_UtcTime.Value, - PrefTimeSeries10.CD_ValueArray.Value - }; - - // find a Segment tagged as Template? - // create the time series tracking information - - _trackSegment = new TrackInstanceTimeSeriesSegment(); - var todel = new List(); - var first = true; - foreach (var smcsegt in smcts.Value.FindAllSemanticIdAs(PrefTimeSeries10.CD_TimeSeriesSegment.Value)) - { - if (smcsegt == null) - continue; - - // relevant? - // TODO (jtikekar, 2023-09-04): check with Andreas - //if ((smcsegt.Kind.Value == ModellingKind.Template) && first) - { - first = false; - - // find all elements with required qualifier FOR A SERIES ELEMENT - smcsegt.Value.RecurseOnSubmodelElements(null, null, (o, parents, sme) => - { - var q = sme.FindQualifierOfType(PrefEnergyModel10.QualiIoTHubSeries); - if (q != null && q.Value != null && q.Value.Length > 0) - { - // found the correct Qualifer, should indicate a variable in the - // TEMPLATED time series - if (!(sme is SubmodelElementCollection smcVar) - || (true != sme.SemanticId?.Matches(PrefTimeSeries10.CD_TimeSeriesVariable.Value))) - return; - - // ok, need to identify record id - var pRecId = smcVar.Value?.FindFirstSemanticIdAs(PrefTimeSeries10.CD_RecordId.Value); - var pDataPoint = smcVar.Value?.FindFirstAnySemanticId(tsvAllowed, invertAllowed: true); - - // proper? - if (("" + pRecId?.Value).Length < 1 || pDataPoint == null) - return; - - // ok, add - _trackSegment.Variables.Add(new TrackInstanceTimeSeriesVariable() - { - SourceId = q.Value, - TemplateRecordId = pRecId?.Value, - TemplateDataPoint = pDataPoint, - TemplateVariable = smcVar - }); - } - }); - } - - // remove all the stuff for a clean start - todel.Add(smcsegt); - } - foreach (var del in todel) - smcts.Value.Remove(del); - } - } - - public static void StartAllAsOneThread(IEnumerable instances) - { - if (instances == null) - return; - - var t = new Thread(() => - { - var storedInstances = instances.ToArray(); - while (true) - { - foreach (var emi in storedInstances) - emi?.CyclicCheck(); - - Thread.Sleep(100); - } - }); - t.Start(); - } - - private int _testi = 0; - - public void CyclicCheck() - { - ; - CyclicCheckDataPoints(); - CyclicCheckTimeSeries(); - ; - } - - public void CyclicCheckDataPoints() - { - // access - if (_sourceSystem == null || _dataPoint == null) - return; - var timeStamp = DateTime.UtcNow; - - // simply iterate - foreach (var dp in _dataPoint) - { - // any action required? - if (dp?.Sme == null || !dp.IsTrigger(_sourceSystem)) - continue; - - // adopt new value & set - var val = dp.GetValue(_sourceSystem); - UpdateSME( - dp.Sme, - string.Format(CultureInfo.InvariantCulture, "{0}", val), - timeStamp); - } - } - - public void CyclicCheckTimeSeries() - { - // access - if (_sourceSystem == null || _trackSegment == null) - return; - var timeStamp = DateTime.UtcNow; - - // something to be done? - if (!_trackSegment.IsTrigger(_sourceSystem)) - return; - - // test - if (actualSamples != null) - { - _testi++; - UpdateSME(actualSamples, "" + _testi, timeStamp); - } - - // OK, a new sample shall be added to the segment - _trackSegment.TimeStamps.Add(DateTime.UtcNow); - foreach (var tsv in _trackSegment.Variables) - tsv.Values.Add(tsv.GetValue(_sourceSystem)); - - // now check, if the segement should be rendered intermediate or finally - var cnt = _trackSegment.TimeStamps.Count; - var doNextColl = (cnt >= maxSamplesInCollection); - var doIntermediate = (cnt == 1) || (cnt == 3); - - // render on multiple times - if (doIntermediate) - { - if (_trackSegment.SegmentSmc == null) - { - Console.WriteLine("Create segement {0}", samplesCollectionsCount); - - // create new segment - var newSeg = _trackSegment.CreateSegmentSmc( - _sourceSystem, _data, samplesCollectionsCount, totalSamples, timeStamp); - - samplesCollectionsCount++; - - // state initial creation as event .. updates need to follow - AasxRestServerLibrary.AasxRestServer.TestResource.eventMessage.add( - newSeg, "Add", _submodel, (ulong)timeStamp.Ticks); - } - else - { - // update - _trackSegment.UpdateSegmentSmc(_sourceSystem, totalSamples, timeStamp); - } - } - - // final? - if (doNextColl) - { - // do a final update - _trackSegment.UpdateSegmentSmc(_sourceSystem, totalSamples, timeStamp); - - // add to already existing segements .. delete an old one - _existingSegements.Add(_trackSegment.SegmentSmc); - if (_existingSegements.Count > 99) - { - // pop - var first = _existingSegements[0]; - _existingSegements.RemoveAt(0); - - // remove - _data.Value.Remove(first); - _data.SetTimeStamp(timeStamp); - AasxRestServerLibrary.AasxRestServer.TestResource.eventMessage.add( - first, "Remove", _submodel, (ulong)timeStamp.Ticks); - } - - // commit und clear -> will make a new collection - Console.WriteLine("Clear segment"); - totalSamples += _trackSegment.TimeStamps.Count; - _trackSegment.ClearRuntime(); - } - } - - } - } -} diff --git a/src/AasxServerStandardBib/EnergyModel_SourceSystem_Azure.cs b/src/AasxServerStandardBib/EnergyModel_SourceSystem_Azure.cs deleted file mode 100644 index 78aac474f..000000000 --- a/src/AasxServerStandardBib/EnergyModel_SourceSystem_Azure.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using AasxServer; -using AasxTimeSeries; -using AdminShellNS; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Opc.Ua; -using SampleClient; - -namespace AasxDemonstration -{ - /// - /// Empty class for free purpse - /// - public class EnergyModel_SourceSystem_Azure - { - // TODO ERICH - } -} diff --git a/src/AasxServerStandardBib/Exceptions/InvalidIdShortPathException.cs b/src/AasxServerStandardBib/Exceptions/InvalidIdShortPathException.cs index 5708c6450..96a12c135 100644 --- a/src/AasxServerStandardBib/Exceptions/InvalidIdShortPathException.cs +++ b/src/AasxServerStandardBib/Exceptions/InvalidIdShortPathException.cs @@ -1,16 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace AasxServerStandardBib.Exceptions { - public class InvalidIdShortPathException:Exception + public class InvalidIdShortPathException : Exception { public InvalidIdShortPathException(string idShortPath) : base($"Invalid segment {idShortPath} in IdShortPath.") { - } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/GrapevineLoggerConsumers.cs b/src/AasxServerStandardBib/GrapevineLoggerConsumers.cs deleted file mode 100644 index ec82b4cb1..000000000 --- a/src/AasxServerStandardBib/GrapevineLoggerConsumers.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Grapevine.Interfaces.Shared; - -/* Copyright (c) 2018-2019 Festo AG & Co. KG , author: Michael Hoffmeister - -This source code is licensed under the Apache License 2.0 (see LICENSE.txt). - -This source code may use other Open Source software components (see LICENSE.txt). -*/ - - -/* Please notice: the API and REST routes implemented in this version of the source code are not specified and standardised by the -specification Details of the Administration Shell. The hereby stated approach is solely the opinion of its author(s). */ - -namespace AasxMqttClient -{ - public class GrapevineLoggerSuper : IGrapevineLogger - { - // IGrapevineLogger side - - private LogLevel level = LogLevel.Trace; - - public LogLevel Level { get { return level; } set { level = value; } } - - public void Debug(object obj) { if (this.level >= LogLevel.Debug) this.Append("DBG: {0}", obj); } - public void Debug(string message) { if (this.level >= LogLevel.Debug) this.Append("DBG: {0}", message); } - public void Debug(string message, Exception ex) { if (this.level >= LogLevel.Debug) this.Append("DBG: Exception when {0}: {1}", message, ex.ToString()); } - public void Error(string message, Exception ex) { if (this.level >= LogLevel.Error) this.Append("ERR: Exception when {0}: {1}", message, ex.ToString()); } - public void Error(string message) { if (this.level >= LogLevel.Error) this.Append("ERR: {0}", message); } - public void Error(object obj) { if (this.level >= LogLevel.Error) this.Append("ERR: {0}", obj); } - public void Fatal(string message) { if (this.level >= LogLevel.Fatal) this.Append("FTL: {0}", message); } - public void Fatal(object obj) { if (this.level >= LogLevel.Fatal) this.Append("FTL: {0}", obj); } - public void Fatal(string message, Exception ex) { if (this.level >= LogLevel.Fatal) this.Append("FTL: Exception when {0}: {1}", message, ex.ToString()); } - public void Info(string message, Exception ex) { if (this.level >= LogLevel.Info) this.Append("INF: Exception when {0}: {1}", message, ex.ToString()); } - public void Info(string message) { if (this.level >= LogLevel.Info) this.Append("INF: {0}", message); } - public void Info(object obj) { if (this.level >= LogLevel.Info) this.Append("INF: {0}", obj); } - public void Log(LogEvent evt) { if (this.level >= evt.Level) this.Append("{0}", evt.Message); } - public void Trace(string message, Exception ex) { if (this.level >= LogLevel.Debug) this.Append("TRC: Exception when {0}: {1}", message, ex.ToString()); } - public void Trace(string message) { if (this.level >= LogLevel.Trace) this.Append("TRC: {0}", message); } - public void Trace(object obj) { if (this.level >= LogLevel.Trace) this.Append("TRC: {0}", obj); } - public void Warn(string message) { if (this.level >= LogLevel.Warn) this.Append("WRN: {0}", message); } - public void Warn(string message, Exception ex) { if (this.level >= LogLevel.Warn) this.Append("WRN: Exception when {0}: {1}", message, ex.ToString()); } - public void Warn(object obj) { if (this.level >= LogLevel.Warn) this.Append("WRN: {0}", obj); } - - // Consumer side - - public virtual void Append(string msg, params object[] args) - { - } - - } - - public class GrapevineLoggerToConsole : GrapevineLoggerSuper - { - public override void Append(string msg, params object[] args) - { - Console.Error.WriteLine(msg, args); - Console.Error.Flush(); - } - } - - public class GrapevineLoggerToListOfStrings : GrapevineLoggerSuper - { - private List list = new List(); - - public override void Append(string msg, params object[] args) - { - lock (list) - { - list.Add(string.Format(msg, args)); - } - } - - public string Pop() - { - if (list == null || list.Count < 1) - return null; - lock (list) - { - var res = list[0]; - list.RemoveAt(0); - return res; - } - } - } - -} diff --git a/src/AasxServerStandardBib/I40Message.cs b/src/AasxServerStandardBib/I40Message.cs deleted file mode 100644 index f988eaa07..000000000 --- a/src/AasxServerStandardBib/I40Message.cs +++ /dev/null @@ -1,266 +0,0 @@ -using System.Collections.Generic; -/* -Copyright (c) 2019-2020 PHOENIX CONTACT GmbH & Co. KG , author: Andreas Orzelski -Copyright (c) 2018-2020 Festo SE & Co. KG , author: Michael Hoffmeister -*/ - -namespace AasxServer -{ - public class I40SemanticKey - { - public string type; - public string local; - public string value; - public string idType; - } - public class I40SemanticProtocol - { - public List keys; - public I40SemanticProtocol() - { - keys = new List(); - } - } - public class I40Identification - { - public string id; - public string idType; - } - public class I40role - { - public string name; - } - public class I40EndPointID - { - public I40Identification identification; - public I40role role; - } - - public class I40TransmitFrame - { - public I40SemanticProtocol semanticProtocol; - public I40EndPointID sender; - public I40EndPointID receiver; - public string type; //CFP, proposal, acceptporposal, Nested - public string messageId; - public string replyBy; - public string replyTo; - public string conversationId; - } - - public class I40Message - { - public I40TransmitFrame frame; - public List interactionElements; - public I40Message() - { - interactionElements = new List { }; - } - - } - - public class I40Message_Interaction - { - public I40TransmitFrame frame; - public List interactionElements; - public I40Message_Interaction() - { - interactionElements = new List { }; - } - - } - - public class I40MessageHelper - { - public I40Message createConnectProtMessage(string connectNodeName) - { - I40Message _i40Message = new I40Message(); - I40TransmitFrame i40Frame = new I40TransmitFrame(); - i40Frame.type = "HeartBeat"; - i40Frame.replyBy = "RESTAPI"; - i40Frame.replyTo = "RESTAPI"; - - I40EndPointID sender = new I40EndPointID(); - I40EndPointID receiver = new I40EndPointID(); - I40Identification seID = new I40Identification(); - I40role seRole = new I40role(); - - I40Identification reID = new I40Identification(); - I40role reRole = new I40role(); - - seID.id = connectNodeName; - seID.idType = "idShort"; - seRole.name = "AASXServerConnect"; - sender.identification = seID; - sender.role = seRole; - i40Frame.sender = sender; - - reID.id = "VWS_RIC"; - reID.idType = "idShort"; - reRole.name = "ConnectProtocol"; - receiver.identification = reID; - receiver.role = reRole; - i40Frame.receiver = receiver; - - I40SemanticKey i40Key = new I40SemanticKey(); - i40Key.type = "GlobalReference"; - i40Key.local = "local"; - i40Key.value = "heartbeat"; - i40Key.idType = "False"; - - I40SemanticProtocol semanticProtocol = new I40SemanticProtocol(); - semanticProtocol.keys.Add(i40Key); - - i40Frame.semanticProtocol = semanticProtocol; - i40Frame.messageId = connectNodeName + 1; - - _i40Message.frame = i40Frame; - - return _i40Message; - } - public I40Message createDescriptorMessage(string connectNodeName) - { - I40Message _i40Message = new I40Message(); - I40TransmitFrame i40Frame = new I40TransmitFrame(); - i40Frame.type = "register"; - i40Frame.replyBy = "RESTAPI"; - i40Frame.replyTo = "RESTAPI"; - - I40EndPointID sender = new I40EndPointID(); - I40EndPointID receiver = new I40EndPointID(); - I40Identification seID = new I40Identification(); - I40role seRole = new I40role(); - - I40Identification reID = new I40Identification(); - I40role reRole = new I40role(); - - seID.id = connectNodeName; - seID.idType = "idShort"; - seRole.name = "AASXServerConnect"; - sender.identification = seID; - sender.role = seRole; - i40Frame.sender = sender; - - reID.id = "VWS_RIC"; - reID.idType = "idShort"; - reRole.name = "RegistryHandler"; - receiver.identification = reID; - receiver.role = reRole; - i40Frame.receiver = receiver; - - I40SemanticKey i40Key = new I40SemanticKey(); - i40Key.type = "GlobalReference"; - i40Key.local = "local"; - i40Key.value = "registration"; - i40Key.idType = "False"; - - I40SemanticProtocol semanticProtocol = new I40SemanticProtocol(); - semanticProtocol.keys.Add(i40Key); - - i40Frame.semanticProtocol = semanticProtocol; - i40Frame.messageId = connectNodeName + 1; - _i40Message.frame = i40Frame; - - return _i40Message; - } - - public I40Message createInteractionMessage(string connectNodeName, - string receiverId, string receiverRole, string senderRole, string messageType, - string replyBy, string replyTo) - { - I40Message _i40Message = new I40Message(); - I40TransmitFrame i40Frame = new I40TransmitFrame(); - i40Frame.type = messageType; - i40Frame.replyBy = replyBy; - i40Frame.replyTo = replyTo; - - I40EndPointID sender = new I40EndPointID(); - I40EndPointID receiver = new I40EndPointID(); - I40Identification seID = new I40Identification(); - I40role seRole = new I40role(); - - I40Identification reID = new I40Identification(); - I40role reRole = new I40role(); - - seID.id = connectNodeName; - seID.idType = "idShort"; - seRole.name = senderRole; - sender.identification = seID; - sender.role = seRole; - i40Frame.sender = sender; - - reID.id = receiverId; - reID.idType = "idShort"; - reRole.name = receiverRole; - receiver.identification = reID; - receiver.role = reRole; - i40Frame.receiver = receiver; - - I40SemanticKey i40Key = new I40SemanticKey(); - i40Key.type = "AasxConnect"; - i40Key.local = "local"; - i40Key.value = "ovgu.de/http://www.vdi.de/gma720/vdi2193_2/bidding"; - i40Key.idType = "False"; - - I40SemanticProtocol semanticProtocol = new I40SemanticProtocol(); - semanticProtocol.keys.Add(i40Key); - - i40Frame.semanticProtocol = semanticProtocol; - i40Frame.messageId = connectNodeName + "1"; - _i40Message.frame = i40Frame; - - return _i40Message; - } - - - public I40Message_Interaction createBiddingMessage(string connectNodeName, - string receiverId, string receiverRole, string senderRole, string messageType, - string replyBy, string replyTo, string conversationId, int messageCount) - { - I40Message_Interaction _i40Message = new I40Message_Interaction(); - I40TransmitFrame i40Frame = new I40TransmitFrame(); - i40Frame.type = messageType; - i40Frame.replyBy = replyBy; - i40Frame.replyTo = replyTo; - - I40EndPointID sender = new I40EndPointID(); - I40EndPointID receiver = new I40EndPointID(); - I40Identification seID = new I40Identification(); - I40role seRole = new I40role(); - - I40Identification reID = new I40Identification(); - I40role reRole = new I40role(); - - seID.id = connectNodeName; - seID.idType = "idShort"; - seRole.name = senderRole; - sender.identification = seID; - sender.role = seRole; - i40Frame.sender = sender; - - reID.id = receiverId; - reID.idType = "idShort"; - reRole.name = receiverRole; - receiver.identification = reID; - receiver.role = reRole; - i40Frame.receiver = receiver; - - I40SemanticKey i40Key = new I40SemanticKey(); - i40Key.type = "AasxConnect"; - i40Key.local = "local"; - i40Key.value = "ovgu.de/http://www.vdi.de/gma720/vdi2193_2/bidding"; - i40Key.idType = "False"; - - I40SemanticProtocol semanticProtocol = new I40SemanticProtocol(); - semanticProtocol.keys.Add(i40Key); - - i40Frame.semanticProtocol = semanticProtocol; - i40Frame.conversationId = conversationId; - i40Frame.messageId = "AASXServerConnect" + messageCount.ToString(); - _i40Message.frame = i40Frame; - - return _i40Message; - } - - } -} diff --git a/src/AasxServerStandardBib/MonitoredItemQueue.cs b/src/AasxServerStandardBib/MonitoredItemQueue.cs deleted file mode 100644 index 57ac1194f..000000000 --- a/src/AasxServerStandardBib/MonitoredItemQueue.cs +++ /dev/null @@ -1,386 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Opc.Ua.Sample -{ - /// - /// Provides a queue for data changes. - /// - public class MonitoredItemQueue - { - /// - /// Creates an empty queue. - /// - public MonitoredItemQueue() - { - m_values = null; - m_errors = null; - m_start = -1; - m_end = -1; - m_overflow = -1; - m_discardOldest = false; - m_nextSampleTime = 0; - m_samplingInterval = 0; - } - - #region Public Methods - /// - /// Gets the current queue size. - /// - public uint QueueSize - { - get - { - if (m_values == null) - { - return 0; - } - - return (uint)m_values.Length; - } - } - - /// - /// Sets the sampling interval used when queuing values. - /// - /// The new sampling interval. - public void SetSamplingInterval(double samplingInterval) - { - // substract the previous sampling interval. - if (m_samplingInterval < m_nextSampleTime) - { - m_nextSampleTime -= m_samplingInterval; - } - - // calculate the next sampling interval. - m_samplingInterval = (long)(samplingInterval * TimeSpan.TicksPerMillisecond); - - if (m_samplingInterval > 0) - { - m_nextSampleTime += m_samplingInterval; - } - else - { - m_nextSampleTime = 0; - } - } - - /// - /// Sets the queue size. - /// - /// The new queue size. - /// Whether to discard the oldest values if the queue overflows. - /// Specifies which diagnostics which should be kept in the queue. - public void SetQueueSize(uint queueSize, bool discardOldest, DiagnosticsMasks diagnosticsMasks) - { - int length = (int)queueSize; - - if (length < 1) - { - length = 1; - } - - int start = m_start; - int end = m_end; - - // create new queue. - DataValue[] values = new DataValue[length]; - ServiceResult[] errors = null; - - if ((diagnosticsMasks & DiagnosticsMasks.OperationAll) != 0) - { - errors = new ServiceResult[length]; - } - - // copy existing values. - List existingValues = null; - List existingErrors = null; - - if (m_start >= 0) - { - existingValues = new List(); - existingErrors = new List(); - - DataValue value = null; - ServiceResult error = null; - - while (Dequeue(out value, out error)) - { - existingValues.Add(value); - existingErrors.Add(error); - } - } - - // update internals. - m_values = values; - m_errors = errors; - m_start = -1; - m_end = 0; - m_overflow = -1; - m_discardOldest = discardOldest; - - // requeue the data. - if (existingValues != null) - { - for (int ii = 0; ii < existingValues.Count; ii++) - { - Enqueue(existingValues[ii], existingErrors[ii]); - } - } - } - - /// - /// Adds the value to the queue. - /// - /// The value to queue. - /// The error to queue. - public void QueueValue(DataValue value, ServiceResult error) - { - long now = DateTime.UtcNow.Ticks; - - if (m_start >= 0) - { - // check if too soon for another sample. - if (now < m_nextSampleTime) - { - int last = m_end - 1; - - if (last < 0) - { - last = m_values.Length - 1; - } - - // replace last value and error. - m_values[last] = value; - - if (m_errors != null) - { - m_errors[last] = error; - } - - return; - } - } - - // update next sample time. - if (m_nextSampleTime > 0) - { - long delta = now - m_nextSampleTime; - - if (m_samplingInterval > 0 && delta >= 0) - { - m_nextSampleTime += ((delta / m_samplingInterval) + 1) * m_samplingInterval; - } - } - else - { - m_nextSampleTime = now + m_samplingInterval; - } - - // queue next value. - Enqueue(value, error); - } - - /// - /// Publishes the oldest value in the queue. - /// - /// The value. - /// The error associated with the value. - /// True if a value was found. False if the queue is empty. - public bool Publish(out DataValue value, out ServiceResult error) - { - return Dequeue(out value, out error); - } - #endregion - - #region Private Methods - /// - /// Adds the value to the queue. Discards values if the queue is full. - /// - /// The value to add. - /// The error to add. - private void Enqueue(DataValue value, ServiceResult error) - { - // check for empty queue. - if (m_start < 0) - { - m_start = 0; - m_end = 1; - m_overflow = -1; - - m_values[m_start] = value; - - if (m_errors != null) - { - m_errors[m_start] = error; - } - - return; - } - - int next = m_end; - - // check for wrap around. - if (next >= m_values.Length) - { - next = 0; - } - - // check if queue is full. - if (m_start == next) - { - if (!m_discardOldest) - { - m_overflow = m_end - 1; - return; - } - - // remove oldest value. - m_start++; - - if (m_start >= m_values.Length) - { - m_start = 0; - } - - // set overflow bit. - m_overflow = m_start; - } - - // add value. - m_values[next] = value; - - if (m_errors != null) - { - m_errors[next] = error; - } - - m_end = next + 1; - } - - /// - /// Removes a value and an error from the queue. - /// - /// The value removed from the queue. - /// The error removed from the queue. - /// True if a value was found. False if the queue is empty. - private bool Dequeue(out DataValue value, out ServiceResult error) - { - value = null; - error = null; - - // check for empty queue. - if (m_start < 0) - { - return false; - } - - value = m_values[m_start]; - m_values[m_start] = null; - - if (m_errors != null) - { - error = m_errors[m_start]; - m_errors[m_start] = null; - } - - // set the overflow bit. - if (m_overflow == m_start) - { - SetOverflowBit(ref value, ref error); - m_overflow = -1; - } - - m_start++; - - // check if queue has been emptied. - if (m_start == m_end) - { - m_start = -1; - m_end = 0; - } - - // check for wrap around. - else if (m_start >= m_values.Length) - { - m_start = 0; - } - - return true; - } - - /// - /// Sets the overflow bit in the value and error. - /// - /// The value to update. - /// The error to update. - private void SetOverflowBit(ref DataValue value, ref ServiceResult error) - { - if (value != null) - { - StatusCode status = value.StatusCode; - status.Overflow = true; - value.StatusCode = status; - } - - if (error != null) - { - StatusCode status = error.StatusCode; - status.Overflow = true; - - // have to copy before updating because the ServiceResult is invariant. - ServiceResult copy = new ServiceResult( - status, - error.SymbolicId, - error.NamespaceUri, - error.LocalizedText, - error.AdditionalInfo, - error.InnerResult); - - error = copy; - } - } - #endregion - - #region Private Fields - private DataValue[] m_values; - private ServiceResult[] m_errors; - private int m_start; - private int m_end; - private int m_overflow; - private bool m_discardOldest; - private long m_nextSampleTime; - private long m_samplingInterval; - #endregion - } -} diff --git a/src/AasxServerStandardBib/MonitoredNode.cs b/src/AasxServerStandardBib/MonitoredNode.cs deleted file mode 100644 index b7ae90e80..000000000 --- a/src/AasxServerStandardBib/MonitoredNode.cs +++ /dev/null @@ -1,382 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Text; -using Opc.Ua.Server; - -namespace Opc.Ua.Sample -{ - /// - /// Keeps track of the monitored items for a single node. - /// - public class MonitoredNode - { - #region Constructors - /// - /// Initializes the instance with the context for the node being monitored. - /// - public MonitoredNode( - IServerInternal server, - INodeManager nodeManager, - NodeState node) - { - m_server = server; - m_nodeManager = nodeManager; - m_node = node; - } - #endregion - - #region Public Properties - /// - /// The server that the node belongs to. - /// - public IServerInternal Server - { - get { return m_server; } - } - - /// - /// The node manager that the node belongs to. - /// - public INodeManager NodeManager - { - get { return m_nodeManager; } - } - - /// - /// The node being monitored. - /// - public NodeState Node - { - get { return m_node; } - } - - /// - /// Whether the node has any active monitored items for the specified attribute. - /// - public bool IsMonitoringRequired(uint attributeId) - { - if (m_monitoredItems != null) - { - for (int ii = 0; ii < m_monitoredItems.Count; ii++) - { - DataChangeMonitoredItem monitoredItem = m_monitoredItems[ii]; - - if (monitoredItem.AttributeId == attributeId && monitoredItem.MonitoringMode != MonitoringMode.Disabled) - { - return true; - } - } - } - - return false; - } - #endregion - - #region Public Methods - /// - /// Creates a new data change monitored item. - /// - /// The system context. - /// The unique identifier for the monitiored item. - /// The attribute to monitor. - /// The index range to use for array values. - /// The data encoding to return for structured values. - /// The diagnostics masks to use. - /// The timestamps to return. - /// The initial monitoring mode. - /// The handle assigned by the client. - /// The sampling interval. - /// The queue size. - /// Whether to discard the oldest values when the queue overflows. - /// The data change filter to use. - /// The range to use when evaluating a percentage deadband filter. - /// Whether the monitored item should skip the check for a change in value. - /// The new monitored item. - public DataChangeMonitoredItem CreateDataChangeItem( - ISystemContext context, - uint monitoredItemId, - uint attributeId, - NumericRange indexRange, - QualifiedName dataEncoding, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - MonitoringMode monitoringMode, - uint clientHandle, - double samplingInterval, - uint queueSize, - bool discardOldest, - DataChangeFilter filter, - Range range, - bool alwaysReportUpdates) - { - DataChangeMonitoredItem monitoredItem = new DataChangeMonitoredItem( - this, - monitoredItemId, - attributeId, - indexRange, - dataEncoding, - diagnosticsMasks, - timestampsToReturn, - monitoringMode, - clientHandle, - samplingInterval, - queueSize, - discardOldest, - filter, - range, - alwaysReportUpdates); - - if (m_monitoredItems == null) - { - m_monitoredItems = new List(); - m_node.OnStateChanged = OnNodeChange; - } - - m_monitoredItems.Add(monitoredItem); - - return monitoredItem; - } - - /// - /// Creates a new data change monitored item. - /// - /// The system context. - /// The unique identifier for the monitiored item. - /// The attribute to monitor. - /// The index range to use for array values. - /// The data encoding to return for structured values. - /// The diagnostics masks to use. - /// The timestamps to return. - /// The initial monitoring mode. - /// The handle assigned by the client. - /// The sampling interval. - /// Whether the monitored item should skip the check for a change in value. - /// The new monitored item. - public DataChangeMonitoredItem CreateDataChangeItem( - ISystemContext context, - uint monitoredItemId, - uint attributeId, - NumericRange indexRange, - QualifiedName dataEncoding, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - MonitoringMode monitoringMode, - uint clientHandle, - double samplingInterval, - bool alwaysReportUpdates) - { - return CreateDataChangeItem( - context, - monitoredItemId, - attributeId, - indexRange, - dataEncoding, - diagnosticsMasks, - timestampsToReturn, - monitoringMode, - clientHandle, - samplingInterval, - 0, - false, - null, - null, - alwaysReportUpdates); - } - - /// - /// Deletes the monitored item. - /// - public void DeleteItem(IMonitoredItem monitoredItem) - { - if (m_monitoredItems != null) - { - for (int ii = 0; ii < m_monitoredItems.Count; ii++) - { - if (Object.ReferenceEquals(monitoredItem, m_monitoredItems[ii])) - { - m_monitoredItems.RemoveAt(ii); - break; - } - } - } - } - - /// - /// Handles change events raised by the node. - /// - /// The system context. - /// The node that raised the event. - /// What caused the event to be raised - public void OnNodeChange(ISystemContext context, NodeState state, NodeStateChangeMasks masks) - { - if (m_monitoredItems != null) - { - for (int ii = 0; ii < m_monitoredItems.Count; ii++) - { - DataChangeMonitoredItem monitoredItem = m_monitoredItems[ii]; - - // check if the node has been deleted. - if ((masks & NodeStateChangeMasks.Deleted) != 0) - { - monitoredItem.QueueValue(null, StatusCodes.BadNodeIdUnknown); - continue; - } - - if (monitoredItem.AttributeId == Attributes.Value) - { - if ((masks & NodeStateChangeMasks.Value) != 0) - { - monitoredItem.ValueChanged(context); - } - } - else - { - if ((masks & NodeStateChangeMasks.NonValue) != 0) - { - monitoredItem.ValueChanged(context); - } - } - } - } - } - - /// - /// Subscribes to events produced by the node. - /// - public void SubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription) - { - if (m_eventSubscriptions == null) - { - m_eventSubscriptions = new List(); - } - - if (m_eventSubscriptions.Count == 0) - { - m_node.OnReportEvent = OnReportEvent; - m_node.SetAreEventsMonitored(context, true, true); - } - - for (int ii = 0; ii < m_eventSubscriptions.Count; ii++) - { - if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii])) - { - return; - } - } - - m_eventSubscriptions.Add(eventSubscription); - } - - /// - /// Unsubscribes to events produced by the node. - /// - public void UnsubscribeToEvents(ISystemContext context, IEventMonitoredItem eventSubscription) - { - if (m_eventSubscriptions != null) - { - for (int ii = 0; ii < m_eventSubscriptions.Count; ii++) - { - if (Object.ReferenceEquals(eventSubscription, m_eventSubscriptions[ii])) - { - m_eventSubscriptions.RemoveAt(ii); - - if (m_eventSubscriptions.Count == 0) - { - m_node.SetAreEventsMonitored(context, false, true); - m_node.OnReportEvent = null; - } - - break; - } - } - } - } - - /// - /// Handles events reported by the node. - /// - /// The system context. - /// The node that raised the event. - /// The event to report. - public void OnReportEvent(ISystemContext context, NodeState state, IFilterTarget e) - { - if (m_eventSubscriptions != null) - { - for (int ii = 0; ii < m_eventSubscriptions.Count; ii++) - { - m_eventSubscriptions[ii].QueueEvent(e); - } - } - } - - /// - /// Resends the events for any conditions belonging to the node or its children. - /// - /// The system context. - /// The item to refresh. - public void ConditionRefresh( - ISystemContext context, - IEventMonitoredItem monitoredItem) - { - if (m_eventSubscriptions != null) - { - for (int ii = 0; ii < m_eventSubscriptions.Count; ii++) - { - // only process items monitoring this node. - if (!Object.ReferenceEquals(monitoredItem, m_eventSubscriptions[ii])) - { - continue; - } - - // get the set of condition events for the node and its children. - List events = new List(); - m_node.ConditionRefresh(context, events, true); - - // report the events to the monitored item. - for (int jj = 0; jj < events.Count; jj++) - { - monitoredItem.QueueEvent(events[jj]); - } - } - } - } - #endregion - - #region Private Fields - private IServerInternal m_server; - private INodeManager m_nodeManager; - private NodeState m_node; - private List m_eventSubscriptions; - private List m_monitoredItems; - #endregion - } -} diff --git a/src/AasxServerStandardBib/MqttClient.cs b/src/AasxServerStandardBib/MqttClient.cs deleted file mode 100644 index 204d9a900..000000000 --- a/src/AasxServerStandardBib/MqttClient.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using AdminShellNS; -using MQTTnet; -using MQTTnet.Client; -using MQTTnet.Client.Options; - -/* Copyright (c) 2018-2019 Festo AG & Co. KG , author: Michael Hoffmeister - Copyright (c) 2019 Phoenix Contact GmbH & Co. KG , author: Andreas Orzelski - Copyright (c) 2019 Fraunhofer IOSB-INA Lemgo, eine rechtlich nicht selbständige Einrichtung der Fraunhofer-Gesellschaft - zur Förderung der angewandten Forschung e.V. , author: Florian Pethig - -This source code is licensed under the Apache License 2.0 (see LICENSE.txt). - -This source code may use other Open Source software components (see LICENSE.txt). -*/ - -/* For Mqtt Content: - -MIT License - -MQTTnet Copyright (c) 2016-2019 Christian Kratky -*/ - -namespace AasxMqttClient -{ - public class MqttClient - { - public MqttClient() - { - - } - - static int lastAASEnv = 0; - static int lastAAS = 0; - static int lastSubmodel = 0; - public static async Task StartAsync(AdminShellPackageEnv[] package, GrapevineLoggerSuper logger = null) - { - // Create TCP based options using the builder. - var options = new MqttClientOptionsBuilder() - .WithClientId("AASXPackageXplorer MQTT Client") - .WithTcpServer("localhost", 1883) - .Build(); - - //create MQTT Client and Connect using options above - IMqttClient mqttClient = new MqttFactory().CreateMqttClient(); - await mqttClient.ConnectAsync(options); - - int iAASEnv = 0; - for (iAASEnv = 0; iAASEnv < package.Length; iAASEnv++) - { - if (iAASEnv == lastAASEnv && package[iAASEnv] != null) - { - //publish AAS to AAS Topic - foreach (AssetAdministrationShell aas in package[iAASEnv].AasEnv.AssetAdministrationShells) - { - - - //publish submodels - int iSubmodel = 0; - foreach (var sm in package[iAASEnv].AasEnv.Submodels) - { - if (iSubmodel == lastSubmodel) - { - Console.WriteLine("Publish MQTT AAS " + aas.IdShort + " Submodel_" + sm.IdShort); - - var message2 = new MqttApplicationMessageBuilder() - .WithTopic("Submodel_" + sm.IdShort) - .WithPayload(Newtonsoft.Json.JsonConvert.SerializeObject(sm)) - .WithExactlyOnceQoS() - .WithRetainFlag() - .Build(); - - await mqttClient.PublishAsync(message2); - lastSubmodel++; - iSubmodel = -1; - break; - } - iSubmodel++; - } - if (iSubmodel != -1) - { - lastSubmodel = 0; - lastAASEnv++; - } - break; - } - break; - } - } - if (package[lastAASEnv] == null) - { - lastAASEnv = 0; - } - } - } -} diff --git a/src/AasxServerStandardBib/MqttServer.cs b/src/AasxServerStandardBib/MqttServer.cs deleted file mode 100644 index 6c2df6260..000000000 --- a/src/AasxServerStandardBib/MqttServer.cs +++ /dev/null @@ -1,34 +0,0 @@ -using MQTTnet; -using MQTTnet.Server; -using System.Threading.Tasks; - -/* For Mqtt Content: - -MIT License - -MQTTnet Copyright (c) 2016-2019 Christian Kratky -*/ - -namespace AasxMqttServer -{ - class MqttServer - { - IMqttServer mqttServer; - - public MqttServer() - { - mqttServer = new MqttFactory().CreateMqttServer(); - } - - public async Task MqttSeverStartAsync() - { - //Start a MQTT server. - await mqttServer.StartAsync(new MqttServerOptions()); - } - - public async Task MqttSeverStopAsync() - { - await mqttServer.StopAsync(); - } - } -} diff --git a/src/AasxServerStandardBib/MultiTupleDictionary.cs b/src/AasxServerStandardBib/MultiTupleDictionary.cs deleted file mode 100644 index 7adaa29b9..000000000 --- a/src/AasxServerStandardBib/MultiTupleDictionary.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Collections.Generic; - -namespace AasxUtils -{ - public abstract class MultiTupleBase - { } - - [JetBrains.Annotations.UsedImplicitly] - public class MultiTuple2 : MultiTupleBase - { - public T one; - public MultiTuple2(T one) - { - this.one = one; - } - } - - [JetBrains.Annotations.UsedImplicitly] - public class MultiTuple2 : MultiTupleBase - { - public T one; - public U two; - public MultiTuple2(T one, U two) - { - this.one = one; - this.two = two; - } - } - - [JetBrains.Annotations.UsedImplicitly] - public class MultiTuple3 : MultiTupleBase - { - public T one; - public U two; - public V three; - public MultiTuple3(T one, U two, V three) - { - this.one = one; - this.two = two; - this.three = three; - } - } - - [JetBrains.Annotations.UsedImplicitly] - public class MultiTupleDictionary - { - private Dictionary> dict = new Dictionary>(); - - public void Add(KEY key, MT mt) - { - if (dict.ContainsKey(key)) - dict[key].Add(mt); - else - { - dict.Add(key, new List()); - dict[key].Add(mt); - } - } - - public bool ContainsKey(KEY key) - { - return dict.ContainsKey(key); - } - - public List this[KEY key] - { - get - { - if (key == null || !dict.ContainsKey(key)) - return null; - return dict[key]; - } - } - } -} diff --git a/src/AasxServerStandardBib/NodeStateCollection.cs b/src/AasxServerStandardBib/NodeStateCollection.cs deleted file mode 100644 index c909aedd4..000000000 --- a/src/AasxServerStandardBib/NodeStateCollection.cs +++ /dev/null @@ -1,627 +0,0 @@ -/* Copyright (c) 1996-2019 The OPC Foundation. All rights reserved. - The source code in this file is covered under a dual-license scenario: - - RCL: for OPC Foundation members in good-standing - - GPL V2: everybody else - RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/ - GNU General Public License as published by the Free Software Foundation; - version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2 - This source code is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -*/ -#if _hidden_ - -using System; -using System.Collections.Generic; -using System.Xml; -using System.Text; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; - -namespace Opc.Ua -{ - /// - /// Stores a collection of nodes. - /// - public class NodeStateCollection : List - { -#region Constructors - /// - /// Initializes a new instance of the class. - /// - public NodeStateCollection() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The initial capacity. - public NodeStateCollection(int capacity) : base(capacity) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The collection whose elements are copied to the new list. - /// - /// is null. - /// - public NodeStateCollection(IEnumerable collection) : base(collection) - { - } -#endregion - -#region Public Methods - /// - /// Writes the collection to a stream using the NodeSet schema. - /// - public void SaveAsNodeSet(ISystemContext context, Stream ostrm) - { - NodeTable nodeTable = new NodeTable(context.NamespaceUris, context.ServerUris, null); - - for (int ii = 0; ii < this.Count; ii++) - { - try - { - this[ii].Export(context, nodeTable); - } catch (Exception ex) - { - ; - } - } - - NodeSet nodeSet = new NodeSet(); - - foreach (ILocalNode node in nodeTable) - { - nodeSet.Add(node, nodeTable.NamespaceUris, nodeTable.ServerUris); - } - - XmlWriterSettings settings = new XmlWriterSettings(); - - settings.Encoding = Encoding.UTF8; - settings.CloseOutput = true; - settings.ConformanceLevel = ConformanceLevel.Document; - settings.Indent = true; - - using (XmlWriter writer = XmlWriter.Create(ostrm, settings)) - { - DataContractSerializer serializer = new DataContractSerializer(typeof(NodeSet)); - serializer.WriteObject(writer, nodeSet); - } - } - -#region Well-Known Aliases - /// - /// Stores a well known alias. - /// - private struct AliasToUse - { - public AliasToUse(string alias, NodeId nodeId) - { - Alias = alias; - NodeId = nodeId; - } - - public string Alias; - public NodeId NodeId; - } - - /// - /// The list of aliases to use. - /// - private AliasToUse[] s_AliasesToUse = new AliasToUse[] - { - new AliasToUse(BrowseNames.Boolean, DataTypeIds.Boolean), - new AliasToUse(BrowseNames.SByte, DataTypeIds.SByte), - new AliasToUse(BrowseNames.Byte, DataTypeIds.Byte), - new AliasToUse(BrowseNames.Int16, DataTypeIds.Int16), - new AliasToUse(BrowseNames.UInt16, DataTypeIds.UInt16), - new AliasToUse(BrowseNames.Int32, DataTypeIds.Int32), - new AliasToUse(BrowseNames.UInt32, DataTypeIds.UInt32), - new AliasToUse(BrowseNames.Int64, DataTypeIds.Int64), - new AliasToUse(BrowseNames.UInt64, DataTypeIds.UInt64), - new AliasToUse(BrowseNames.Float, DataTypeIds.Float), - new AliasToUse(BrowseNames.Double, DataTypeIds.Double), - new AliasToUse(BrowseNames.DateTime, DataTypeIds.DateTime), - new AliasToUse(BrowseNames.String, DataTypeIds.String), - new AliasToUse(BrowseNames.ByteString, DataTypeIds.ByteString), - new AliasToUse(BrowseNames.Guid, DataTypeIds.Guid), - new AliasToUse(BrowseNames.XmlElement, DataTypeIds.XmlElement), - new AliasToUse(BrowseNames.NodeId, DataTypeIds.NodeId), - new AliasToUse(BrowseNames.ExpandedNodeId, DataTypeIds.ExpandedNodeId), - new AliasToUse(BrowseNames.QualifiedName, DataTypeIds.QualifiedName), - new AliasToUse(BrowseNames.LocalizedText, DataTypeIds.LocalizedText), - new AliasToUse(BrowseNames.StatusCode, DataTypeIds.StatusCode), - new AliasToUse(BrowseNames.Structure, DataTypeIds.Structure), - new AliasToUse(BrowseNames.Number, DataTypeIds.Number), - new AliasToUse(BrowseNames.Integer, DataTypeIds.Integer), - new AliasToUse(BrowseNames.UInteger, DataTypeIds.UInteger), - new AliasToUse(BrowseNames.HasComponent, ReferenceTypeIds.HasComponent), - new AliasToUse(BrowseNames.HasProperty, ReferenceTypeIds.HasProperty), - new AliasToUse(BrowseNames.Organizes, ReferenceTypeIds.Organizes), - new AliasToUse(BrowseNames.HasEventSource, ReferenceTypeIds.HasEventSource), - new AliasToUse(BrowseNames.HasNotifier, ReferenceTypeIds.HasNotifier), - new AliasToUse(BrowseNames.HasSubtype, ReferenceTypeIds.HasSubtype), - new AliasToUse(BrowseNames.HasTypeDefinition, ReferenceTypeIds.HasTypeDefinition), - new AliasToUse(BrowseNames.HasModellingRule, ReferenceTypeIds.HasModellingRule), - new AliasToUse(BrowseNames.HasEncoding, ReferenceTypeIds.HasEncoding), - new AliasToUse(BrowseNames.HasDescription, ReferenceTypeIds.HasDescription) - }; -#endregion - - /// - /// Writes the collection to a stream using the Opc.Ua.Schema.UANodeSet schema. - /// - public void SaveAsNodeSet2(ISystemContext context, Stream ostrm) - { - SaveAsNodeSet2(context, ostrm, null, false); - } - - /// - /// Writes the collection to a stream using the Opc.Ua.Schema.UANodeSet schema. - /// - public void SaveAsNodeSet2(ISystemContext context, Stream ostrm, string version, bool filterSingleNodeIds) - { - Opc.Ua.Export.UANodeSet nodeSet = new Opc.Ua.Export.UANodeSet(); - nodeSet.LastModified = DateTime.UtcNow; - nodeSet.LastModifiedSpecified = true; - - for (int ii = 0; ii < s_AliasesToUse.Length; ii++) - { - nodeSet.AddAlias(context, s_AliasesToUse[ii].Alias, s_AliasesToUse[ii].NodeId); - } - - for (int ii = 0; ii < this.Count; ii++) - { - nodeSet.Export(context, this[ii]); - } - - /* - if (true) - { - var txt = new System.IO.StreamWriter("nodes.txt"); - foreach (var x in nodeSet.Items) - txt.WriteLine(x.NodeId); - txt.Close(); - } - */ - - if (filterSingleNodeIds) - { - // MIHO: There might be DOUBLE nodeIds in the the set!!!!!!!!!! WTF!!!!!!!!!!!!! - // Brutally eliminate them - var nodup = new List(); - foreach (var it in nodeSet.Items) - { - var found = false; - foreach (var it2 in nodup) - if (it.NodeId == it2.NodeId) - found = true; - if (found) - continue; - nodup.Add(it); - } - nodeSet.Items = nodup.ToArray(); - } - - nodeSet.Write(ostrm); - } - - /// - /// Writes the schema information to a static XML export file. - /// - public void SaveAsXml(ISystemContext context, Stream ostrm) - { - SaveAsXml(context, ostrm, false); - } - - /// - /// Writes the schema information to a static XML export file. - /// - public void SaveAsXml(ISystemContext context, Stream ostrm, bool keepStreamOpen) - { - XmlWriterSettings settings = new XmlWriterSettings(); - - settings.Encoding = Encoding.UTF8; - settings.CloseOutput = !keepStreamOpen; - settings.ConformanceLevel = ConformanceLevel.Document; - settings.Indent = true; - - ServiceMessageContext messageContext = new ServiceMessageContext(); - - messageContext.NamespaceUris = context.NamespaceUris; - messageContext.ServerUris = context.ServerUris; - messageContext.Factory = context.EncodeableFactory; - - using (XmlWriter writer = XmlWriter.Create(ostrm, settings)) - { - XmlQualifiedName root = new XmlQualifiedName("ListOfNodeState", Namespaces.OpcUaXsd); - XmlEncoder encoder = new XmlEncoder(root, writer, messageContext); - - encoder.SaveStringTable("NamespaceUris", "NamespaceUri", context.NamespaceUris); - encoder.SaveStringTable("ServerUris", "ServerUri", context.ServerUris); - - for (int ii = 0; ii < this.Count; ii++) - { - NodeState state = this[ii]; - - if (state != null) - { - state.SaveAsXml(context, encoder); - } - } - - encoder.Close(); - } - } - - /// - /// Writes the collection to a binary stream. The stream is closed by this method. - /// - public void SaveAsBinary(ISystemContext context, Stream ostrm) - { - ServiceMessageContext messageContext = new ServiceMessageContext(); - - messageContext.NamespaceUris = context.NamespaceUris; - messageContext.ServerUris = context.ServerUris; - messageContext.Factory = context.EncodeableFactory; - - BinaryEncoder encoder = new BinaryEncoder(ostrm, messageContext); - - encoder.SaveStringTable(context.NamespaceUris); - encoder.SaveStringTable(context.ServerUris); - - encoder.WriteInt32(null, this.Count); - - for (int ii = 0; ii < this.Count; ii++) - { - NodeState state = this[ii]; - state.SaveAsBinary(context, encoder); - } - - encoder.Close(); - } - - /// - /// Reads the schema information from a XML document. - /// - public void LoadFromBinary(ISystemContext context, Stream istrm, bool updateTables) - { - ServiceMessageContext messageContext = new ServiceMessageContext(); - - messageContext.NamespaceUris = context.NamespaceUris; - messageContext.ServerUris = context.ServerUris; - messageContext.Factory = context.EncodeableFactory; - - using (BinaryDecoder decoder = new BinaryDecoder(istrm, messageContext)) - { - // check if a namespace table was provided. - NamespaceTable namespaceUris = new NamespaceTable(); - - if (!decoder.LoadStringTable(namespaceUris)) - { - namespaceUris = null; - } - - // update namespace table. - if (updateTables) - { - if (namespaceUris != null && context.NamespaceUris != null) - { - for (int ii = 0; ii < namespaceUris.Count; ii++) - { - context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii)); - } - } - } - - // check if a server uri table was provided. - StringTable serverUris = new StringTable(); - - if (namespaceUris != null && namespaceUris.Count > 1) - { - serverUris.Append(namespaceUris.GetString(1)); - } - - if (!decoder.LoadStringTable(serverUris)) - { - serverUris = null; - } - - // update server table. - if (updateTables) - { - if (serverUris != null && context.ServerUris != null) - { - for (int ii = 0; ii < serverUris.Count; ii++) - { - context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii)); - } - } - } - - // setup the mappings to use during decoding. - decoder.SetMappingTables(namespaceUris, serverUris); - - int count = decoder.ReadInt32(null); - - for (int ii = 0; ii < count; ii++) - { - NodeState state = NodeState.LoadNode(context, decoder); - this.Add(state); - } - } - } - - /// - /// Reads the schema information from a XML document. - /// - public void LoadFromXml(ISystemContext context, Stream istrm, bool updateTables) - { - ServiceMessageContext messageContext = new ServiceMessageContext(); - - messageContext.NamespaceUris = context.NamespaceUris; - messageContext.ServerUris = context.ServerUris; - messageContext.Factory = context.EncodeableFactory; - - using (XmlReader reader = XmlReader.Create(istrm)) - { - XmlQualifiedName root = new XmlQualifiedName("ListOfNodeState", Namespaces.OpcUaXsd); - XmlDecoder decoder = new XmlDecoder(null, reader, messageContext); - - NamespaceTable namespaceUris = new NamespaceTable(); - - if (!decoder.LoadStringTable("NamespaceUris", "NamespaceUri", namespaceUris)) - { - namespaceUris = null; - } - - // update namespace table. - if (updateTables) - { - if (namespaceUris != null && context.NamespaceUris != null) - { - for (int ii = 0; ii < namespaceUris.Count; ii++) - { - context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii)); - } - } - } - - StringTable serverUris = new StringTable(); - - if (!decoder.LoadStringTable("ServerUris", "ServerUri", context.ServerUris)) - { - serverUris = null; - } - - // update server table. - if (updateTables) - { - if (serverUris != null && context.ServerUris != null) - { - for (int ii = 0; ii < serverUris.Count; ii++) - { - context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii)); - } - } - } - - // set mapping. - decoder.SetMappingTables(namespaceUris, serverUris); - - decoder.PushNamespace(Namespaces.OpcUaXsd); - - NodeState state = NodeState.LoadNode(context, decoder); - - while (state != null) - { - this.Add(state); - - state = NodeState.LoadNode(context, decoder); - } - - decoder.Close(); - } - } - - /// - /// Loads the nodes from an embedded resource. - /// - /// The context. - /// The resource path. - /// The assembly containing the resource. - /// if set to true the namespace and server tables are updated with any new URIs. - public void LoadFromResource(ISystemContext context, string resourcePath, Assembly assembly, bool updateTables) - { - if (resourcePath == null) throw new ArgumentNullException("resourcePath"); - - if (assembly == null) throw new ArgumentNullException("assembly"); - - Stream istrm = assembly.GetManifestResourceStream(resourcePath); - if (istrm == null) - { - // try to load from app directory - FileInfo file = new FileInfo(resourcePath); - istrm = file.OpenRead(); - if (istrm == null) - { - throw ServiceResultException.Create(StatusCodes.BadDecodingError, "Could not load nodes from resource: {0}", resourcePath); - } - } - - LoadFromXml(context, istrm, updateTables); - } - - /// - /// Loads the nodes from an embedded resource. - /// - /// The context. - /// The resource path. - /// The assembly containing the resource. - /// if set to true the namespace and server tables are updated with any new URIs. - public void LoadFromBinaryResource(ISystemContext context, string resourcePath, Assembly assembly, bool updateTables) - { - if (resourcePath == null) throw new ArgumentNullException("resourcePath"); - - if (assembly == null) throw new ArgumentNullException("assembly"); - - Stream istrm = assembly.GetManifestResourceStream(resourcePath); - if (istrm == null) - { - // try to load from app directory - FileInfo file = new FileInfo(resourcePath); - istrm = file.OpenRead(); - if (istrm == null) - { - throw ServiceResultException.Create(StatusCodes.BadDecodingError, "Could not load nodes from resource: {0}", resourcePath); - } - } - - LoadFromBinary(context, istrm, updateTables); - } -#endregion - } - - /// - /// A class that creates instances of nodes based on the paramters provided. - /// - public class NodeStateFactory - { - /// - /// Creates a new instance. - /// - /// The current context. - /// The parent. - /// The node class. - /// The browse name. - /// The reference type between the parent and the node. - /// The type definition. - /// Returns null if the type is not known. - public virtual NodeState CreateInstance( - ISystemContext context, - NodeState parent, - NodeClass nodeClass, - QualifiedName browseName, - NodeId referenceTypeId, - NodeId typeDefinitionId) - { - NodeState child = null; - - if (m_types != null && !NodeId.IsNull(typeDefinitionId)) - { - Type type = null; - - if (m_types.TryGetValue(typeDefinitionId, out type)) - { - return Activator.CreateInstance(type, parent) as NodeState; - } - } - - switch (nodeClass) - { - case NodeClass.Variable: - { - if (context.TypeTable != null && context.TypeTable.IsTypeOf(referenceTypeId, ReferenceTypeIds.HasProperty)) - { - child = new PropertyState(parent); - break; - } - - child = new BaseDataVariableState(parent); - break; - } - - case NodeClass.Object: - { - child = new BaseObjectState(parent); - break; - } - - case NodeClass.Method: - { - child = new MethodState(parent); - break; - } - - case NodeClass.ReferenceType: - { - child = new ReferenceTypeState(); - break; - } - - case NodeClass.ObjectType: - { - child = new BaseObjectTypeState(); - break; - } - - case NodeClass.VariableType: - { - child = new BaseDataVariableTypeState(); - break; - } - - case NodeClass.DataType: - { - child = new DataTypeState(); - break; - } - - case NodeClass.View: - { - child = new ViewState(); - break; - } - - default: - { - child = null; - break; - } - } - - return child; - } - - /// - /// Registers a type with the factory. - /// - /// The type definition. - /// The system type. - public void RegisterType(NodeId typeDefinitionId, Type type) - { - if (NodeId.IsNull(typeDefinitionId)) throw new ArgumentNullException("typeDefinitionId"); - if (type == null) throw new ArgumentNullException("type"); - - if (m_types == null) - { - m_types = new NodeIdDictionary(); - } - - m_types[typeDefinitionId] = type; - } - - /// - /// Unregisters a type with the factory. - /// - /// The type definition. - public void UnRegisterType(NodeId typeDefinitionId) - { - if (NodeId.IsNull(typeDefinitionId)) throw new ArgumentNullException("typeDefinitionId"); - - if (m_types != null) - { - m_types.Remove(typeDefinitionId); - } - } - - private NodeIdDictionary m_types; - } -} - -#endif diff --git a/src/AasxServerStandardBib/Opc.Ua.SampleClient.Config.xml b/src/AasxServerStandardBib/Opc.Ua.SampleClient.Config.xml deleted file mode 100644 index f0c060ec6..000000000 --- a/src/AasxServerStandardBib/Opc.Ua.SampleClient.Config.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - UA Core Sample Client - urn:localhost:OPCFoundation:CoreSampleClient - http://opcfoundation.org/UA/CoreSampleClient - Client_1 - - - - - - X509Store - CurrentUser\My - CN=UA Core Sample Client, C=US, S=Arizona, O=OPC Foundation, DC=localhost - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/issuer - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/trusted - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/rejected - - - - false - - - - - - - 600000 - 1048576 - 4194304 - 65535 - 4194304 - 65535 - 300000 - 3600000 - - - - - - - 600000 - - - - opc.tcp://{0}:4840/UADiscovery - - - - - - - 10000 - - - - %LocalApplicationData%/Logs/Opc.Ua.SampleClient.log.txt - true - - - - - - - - - - - - 519 - - - - true - - \ No newline at end of file diff --git a/src/AasxServerStandardBib/Opc.Ua.SampleServer.Config.xml b/src/AasxServerStandardBib/Opc.Ua.SampleServer.Config.xml deleted file mode 100644 index b04618e64..000000000 --- a/src/AasxServerStandardBib/Opc.Ua.SampleServer.Config.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - UA Core Sample Server - urn:localhost:OPCFoundation:CoreSampleServer - http://opcfoundation.org/UA/CoreSampleServer - Server_0 - - - - - - X509Store - CurrentUser\My - CN=UA Core Sample Server, C=US, S=Arizona, O=OPC Foundation, DC=localhost - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/issuer - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/trusted - - - - - Directory - %LocalApplicationData%/OPC Foundation/pki/rejected - - - - false - - - - - - - 600000 - 1048576 - 4194304 - 65535 - 4194304 - 65535 - 300000 - 3600000 - - - - - opc.tcp://0.0.0.0:51210/UA/SampleServer - https://0.0.0.0:51212/UA/SampleServer/ - - - - - - - - SignAndEncrypt_3 - http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 - - - - None_1 - http://opcfoundation.org/UA/SecurityPolicy#None - - - Sign_2 - - - - SignAndEncrypt_3 - - - - - 5 - 100 - 2000 - - - - Anonymous_0 - http://opcfoundation.org/UA/SecurityPolicy#None - - - UserName_1 - - - Certificate_2 - - - - false - 100 - 10000 - 3600000 - 10 - 10 - 100 - 6000000 - 100 - 3600000 - 50 - 3600000 - 100 - 100 - 1000 - 1000 - - - - opc.tcp://0.0.0.0:4840 - - opc.tcp://0.0.0.0:4840 - DiscoveryServer_3 - - opc.tcp://0.0.0.0:4840 - - - SignAndEncrypt_3 - - - - - 30000 - Opc.Ua.Server.nodes.xml - - 20 - 100 - 10000 - 10000 - - - - Standard UA Server Profile - Data Access Server Facet - Method Server Facet - - 5 - - DA - - - PFX - PEM - - 0 - false - - - - - - - - - UInt32 - 100 - UInt32 - - - Double - 100 - Double - - - - - - - - %LocalApplicationData%/Logs/Opc.Ua.CoreSampleServer.log.txt - true - - - - - - - - - - - - - - - - true - - diff --git a/src/AasxServerStandardBib/PrefEnergyModel10.cs b/src/AasxServerStandardBib/PrefEnergyModel10.cs deleted file mode 100644 index 0e89836ec..000000000 --- a/src/AasxServerStandardBib/PrefEnergyModel10.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace AasxDemonstration -{ - public static class PrefEnergyModel10 - { - public static Key SM_EnergyModel = - new Key(KeyTypes.Submodel, - "https://admin-shell.io/sandbox/pi40/CarbonMonitoring/1/0"); - - public static string QualiIoTHubDataPoint = "IoTHub"; - - public static string QualiIoTHubSeries = "IoTHubSeries"; - } -} diff --git a/src/AasxServerStandardBib/Program.cs b/src/AasxServerStandardBib/Program.cs index f9b6b1df3..b5c601b2f 100644 --- a/src/AasxServerStandardBib/Program.cs +++ b/src/AasxServerStandardBib/Program.cs @@ -1,7 +1,4 @@ -using AasOpcUaServer; -using AasxMqttServer; -using AasxRestServerLibrary; -//using AasxServerStandardBib.Migrations; +using AasxRestServerLibrary; using AdminShellNS; using Extensions; using Jose; @@ -10,15 +7,11 @@ using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Opc.Ua; -using Opc.Ua.Configuration; -using Opc.Ua.Server; using System; using System.Collections.Generic; using System.CommandLine; using System.CommandLine.Help; using System.CommandLine.IO; -using System.ComponentModel; using System.Globalization; using System.IO; using System.IO.Compression; @@ -633,12 +626,6 @@ public static bool loadPackageForSubmodel(string submodelIdentifier, out ISubmod public static void changeDataVersion() { dataVersion++; } public static ulong getDataVersion() { return (dataVersion); } - static Dictionary OPCClients = new Dictionary(); - static readonly object opcclientAddLock = new object(); // object for lock around connecting to an external opc server - - static MqttServer AASMqttServer = new MqttServer(); - - static bool runOPC = false; public static string connectServer = ""; public static string connectNodeName = ""; @@ -698,10 +685,8 @@ private class CommandLineArguments public bool Https { get; set; } public string DataPath { get; set; } public bool Rest { get; set; } - public bool Opc { get; set; } public bool Mqtt { get; set; } public bool DebugWait { get; set; } - public int? OpcClientRate { get; set; } public string[] Connect { get; set; } public string ProxyFile { get; set; } public bool NoSecurity { get; set; } @@ -849,7 +834,6 @@ private static async Task Run(CommandLineArguments a) Console.WriteLine($"Serving the AASXs from: {a.DataPath}"); AasxHttpContextHelper.DataPath = a.DataPath; } - Program.runOPC = a.Opc; Program.noSecurity = a.NoSecurity; Program.edit = a.Edit; Program.readTemp = a.ReadTemp; @@ -870,11 +854,6 @@ private static async Task Run(CommandLineArguments a) Console.WriteLine("secretStringAPI = " + secretStringAPI); } - if (a.OpcClientRate != null && a.OpcClientRate < 200) - { - Console.WriteLine("Recommend an OPC client update rate > 200 ms."); - } - // allocate memory env = new AdminShellPackageEnv[envimax]; envFileName = new string[envimax]; @@ -996,34 +975,6 @@ private static async Task Run(CommandLineArguments a) string fn = null; - if (a.Opc) - { - Boolean is_BaseAddresses = false; - Boolean is_uaString = false; - XmlTextReader reader = new XmlTextReader("Opc.Ua.SampleServer.Config.xml"); - while (reader.Read()) - { - switch (reader.NodeType) - { - case XmlNodeType.Element: // The node is an element. - if (reader.Name == "BaseAddresses") - is_BaseAddresses = true; - if (reader.Name == "ua:String") - is_uaString = true; - break; - case XmlNodeType.Text: //Display the text in each element. - if (is_BaseAddresses && is_uaString) - { - Console.WriteLine("Connect to OPC UA by: {0}", reader.Value); - is_BaseAddresses = false; - is_uaString = false; - } - break; - case XmlNodeType.EndElement: //Display the end of the element. - break; - } - } - } bool createFilesOnly = false; if (System.IO.File.Exists(AasxHttpContextHelper.DataPath + "/FILES.ONLY")) @@ -1412,17 +1363,6 @@ private static async Task Run(CommandLineArguments a) // MICHA MICHA AasxTimeSeries.TimeSeries.timeSeriesInit(); - /* OZOZ - var _energyModelInstances = new List(); - foreach (var penv in AasxServer.Program.env) - { - EnergyModelInstance.TagAllAasAndSm(penv?.AasEnv, DateTime.UtcNow); - _energyModelInstances.AddRange( - EnergyModelInstance.FindAllSmInstances(penv?.AasEnv)); - } - EnergyModelInstance.StartAllAsOneThread(_energyModelInstances); - */ - AasxTask.taskInit(); RunScript(true); @@ -1433,32 +1373,8 @@ private static async Task Run(CommandLineArguments a) isLoading = false; - if (a.Mqtt) - { - AASMqttServer.MqttSeverStartAsync().Wait(); - Console.WriteLine("MQTT Publisher started."); - } - MySampleServer server = null; - if (a.Opc) - { - server = new MySampleServer(_autoAccept: true, _stopTimeout: 0, _aasxEnv: env); - Console.WriteLine("OPC UA Server started.."); - } - - if (a.OpcClientRate != null) // read data by OPC UA - { - // Initial read of OPC values, will quit the program if it returns false - if (!ReadOPCClient(true)) - { - Console.Error.WriteLine("Failed to read from the OPC client."); - return 1; - } - - Console.WriteLine($"OPC client will be updating every: {a.OpcClientRate} milliseconds"); - SetOPCClientTimer((double)a.OpcClientRate); // read again everytime timer expires - } - + SetScriptTimer(1000); // also updates balzor view if (connectServer != "") @@ -1503,73 +1419,9 @@ private static async Task Run(CommandLineArguments a) } Program.signalNewData(3); - if (a.Opc && server != null) + if (connectServer != "" && connectLoop) { - server.Run(); // wait for CTRL-C - } - else - { - // no OPC UA: wait only for CTRL-C - Console.WriteLine("Servers successfully started. Press Ctrl-C to exit..."); - - //jtikekar moved this code to Blazor's Program.cs - //ManualResetEvent quitEvent = new ManualResetEvent(false); - //try - //{ - // Console.CancelKeyPress += (sender, eArgs) => - // { - // quitEvent.Set(); - // //eArgs.Cancel = true; - // }; - //} - //catch - //{ - //} - - //// wait for timeout or Ctrl-C - //quitEvent.WaitOne(Timeout.Infinite); - } - - // wait for RETURN - - if (connectServer != "") - { - /* - HttpClient httpClient; - if (clientHandler != null) - { - httpClient = new HttpClient(clientHandler); - } - else - { - httpClient = new HttpClient(); - } - - string payload = "{ \"source\" : \"" + connectNodeName + "\" }"; - - string content = ""; - try - { - var contentJson = new StringContent(payload, System.Text.Encoding.UTF8, "application/json"); - // httpClient.PostAsync("http://" + connectServer + "/disconnect", contentJson).Wait(); - var result = httpClient.PostAsync(connectServer + "/disconnect", contentJson).Result; - content = ContentToString(result.Content); - } - catch - { - - } - */ - - if (connectLoop) - { - connectLoop = false; - } - } - - if (a.Mqtt) - { - AASMqttServer.MqttSeverStopAsync().Wait(); + connectLoop = false; } AasxRestServer.Stop(); @@ -1613,11 +1465,6 @@ public static void Main(string[] args) new[] {"--data-path"}, "Path to where the AASXs reside"), - - new Option( - new[] {"--opc"}, - "If set, starts the OPC server"), - new Option( new[] {"--mqtt"}, "If set, starts a MQTT publisher"), @@ -1626,11 +1473,6 @@ public static void Main(string[] args) new[] {"--debug-wait"}, "If set, waits for Debugger to attach"), - new Option( - new[] {"--opc-client-rate"}, - "If set, starts an OPC client and refreshes on the given period " + - "(in milliseconds)"), - new Option( new[] {"--proxy-file"}, "If set, parses the proxy information from the given proxy file"), @@ -1705,16 +1547,6 @@ public static void Main(string[] args) rootCommand.Handler = System.CommandLine.Invocation.CommandHandler.Create( async (CommandLineArguments a) => { - /* - if (!(a.Rest || a.Opc || a.Mqtt)) - { - Console.Error.WriteLine($"Please specify --rest and/or --opc and/or --mqtt{nl}"); - new HelpBuilder(new SystemConsole()).Write(rootCommand); - return 1; - } - */ - - //return Run(a); var task = Run(a); task.Wait(); var op = task.Result; @@ -2126,40 +1958,6 @@ public static void connectThreadLoop() envi++; } - // i40language - if (i40LanguageRuntime.isRequester && i40LanguageRuntime.sendFrameJSONRequester.Count != 0) - { - foreach (string s in i40LanguageRuntime.sendFrameJSONRequester) - { - td = new TransmitData - { - source = connectNodeName - }; - - td.type = "i40LanguageRuntime.sendFrameJSONRequester"; - var json = JsonConvert.SerializeObject(s, Newtonsoft.Json.Formatting.Indented); - td.publish.Add(json); - tf.data.Add(td); - } - i40LanguageRuntime.sendFrameJSONRequester.Clear(); - } - if (i40LanguageRuntime.isProvider && i40LanguageRuntime.sendFrameJSONProvider.Count != 0) - { - td = new TransmitData - { - source = connectNodeName - }; - - foreach (string s in i40LanguageRuntime.sendFrameJSONProvider) - { - td.type = "i40LanguageRuntime.sendFrameJSONProvider"; - var json = JsonConvert.SerializeObject(s, Newtonsoft.Json.Formatting.Indented); - td.publish.Add(json); - tf.data.Add(td); - } - i40LanguageRuntime.sendFrameJSONProvider.Clear(); - } - string publish = JsonConvert.SerializeObject(tf, Formatting.Indented); HttpClient httpClient; @@ -2488,22 +2286,6 @@ public static void connectThreadLoop() } } } - - // i40language - if (i40LanguageRuntime.isRequester && td2.type == "i40LanguageRuntime.sendFrameJSONProvider") - { - foreach (string s in td2.publish) - { - i40LanguageRuntime.receivedFrameJSONRequester.Add(JsonConvert.DeserializeObject(s)); - } - } - if (i40LanguageRuntime.isProvider && td2.type == "i40LanguageRuntime.sendFrameJSONRequester") - { - foreach (string s in td2.publish) - { - i40LanguageRuntime.receivedFrameJSONProvider.Add(JsonConvert.DeserializeObject(s)); - } - } } } catch @@ -2569,27 +2351,6 @@ public static void signalNewData(int mode) NewDataAvailable?.Invoke(null, new NewDataAvailableArgs(mode)); } - /* - public static int getSignalNewDataMode() - { - int mode = signalNewDataMode; - signalNewDataMode = 0; - return (mode); - } - */ - - public static void OnOPCClientNextTimedEvent() - { - ReadOPCClient(false); - // RunScript(false); - NewDataAvailable?.Invoke(null, EventArgs.Empty); - } - private static void OnOPCClientNextTimedEvent(Object source, ElapsedEventArgs e) - { - ReadOPCClient(false); - // RunScript(false); - NewDataAvailable?.Invoke(null, EventArgs.Empty); - } private static System.Timers.Timer scriptTimer; private static void SetScriptTimer(double value) @@ -2759,225 +2520,6 @@ private static void OnRestTimedEvent(Object source, ElapsedEventArgs e) } RESTalreadyRunning = false; - - // start MQTT Client as a worker (will start in the background) - var worker = new BackgroundWorker(); - worker.DoWork += async (s1, e1) => - { - - try - { - await AasxMqttClient.MqttClient.StartAsync(env); - } - catch (Exception) - { - } - }; - worker.RunWorkerCompleted += (s1, e1) => - { - - }; - worker.RunWorkerAsync(); - } - - private static Boolean OPCWrite(string nodeId, object value) - /// - /// Writes to (i.e. updates values of) Nodes in the AAS OPC Server - /// - { - if (!runOPC) - { - return true; - } - - AasOpcUaServer.AasModeManager nodeMgr = AasOpcUaServer.AasEntityBuilder.nodeMgr; - - if (nodeMgr == null) - { - // if Server has not started yet, the AasNodeManager is null - Console.WriteLine("OPC NodeManager not initialized."); - return false; - } - - // Find node in Core3OPC Server to update it - BaseVariableState bvs = nodeMgr.Find(nodeId) as BaseVariableState; - - if (bvs == null) - { - Console.WriteLine("node {0} does not exist in server!", nodeId); - return false; - } - var convertedValue = Convert.ChangeType(value, bvs.Value.GetType()); - if (!object.Equals(bvs.Value, convertedValue)) - { - bvs.Value = convertedValue; - // TODO: timestamp UtcNow okay or get this internally from the Server? - bvs.Timestamp = DateTime.UtcNow; - bvs.ClearChangeMasks(null, false); - } - return true; - } - - static Boolean ReadOPCClient(bool initial) - /// - /// Update AAS property values from external OPC servers. - /// Only submodels which have the appropriate qualifier are affected. - /// However, this will attempt to get values for all properties of the submodel. - /// TODO: Possilby add a qualifier to specifiy which values to get? Or NodeIds per alue? - /// - { - if (env == null) - return false; - - lock (Program.changeAasxFile) - { - int i = 0; - while (env[i] != null) - { - foreach (var sm in env[i].AasEnv.Submodels) - { - if (sm != null && sm.IdShort != null) - { - int count = sm.Qualifiers.Count; - if (count != 0) - { - int stopTimeout = Timeout.Infinite; - bool autoAccept = true; - // Variablen aus AAS Qualifiern - string Username = ""; - string Password = ""; - string URL = ""; - int Namespace = 0; - string Path = ""; - - int j = 0; - - while (j < count) // URL, Username, Password, Namespace, Path - { - var p = sm.Qualifiers[j] as Qualifier; - - switch (p.Type) - { - case "OPCURL": // URL - URL = p.Value; - break; - case "OPCUsername": // Username - Username = p.Value; - break; - case "OPCPassword": // Password - Password = p.Value; - break; - case "OPCNamespace": // Namespace - // TODO: if not int, currently throws nondescriptive error - if (int.TryParse(p.Value, out int tmpI)) - Namespace = tmpI; - break; - case "OPCPath": // Path - Path = p.Value; - break; - case "OPCEnvVar": // Only if enviroment variable ist set - // VARIABLE=VALUE - string[] split = p.Value.Split('='); - if (split.Length == 2) - { - string value = ""; - if (envVariables.TryGetValue(split[0], out value)) - { - if (split[1] != value) - URL = ""; // continue - } - } - break; - } - j++; - } - - if (URL == "") - { - continue; - } - - if (URL == "" || Namespace == 0 || Path == "" || (Username == "" && Password != "") || (Username != "" && Password == "")) - { - Console.WriteLine("Incorrent or missing qualifier. Aborting ..."); - return false; - } - if (Username == "" && Password == "") - { - Console.WriteLine("Using Anonymous to login ..."); - } - - // try to get the client from dictionary, else create and add it - SampleClient.UASampleClient client; - lock (Program.opcclientAddLock) - { - if (!OPCClients.TryGetValue(URL, out client)) - { - try - { - // make OPC UA client - client = new SampleClient.UASampleClient(URL, autoAccept, stopTimeout, Username, Password); - Console.WriteLine("Connecting to external OPC UA Server at {0} with {1} ...", URL, sm.IdShort); - client.ConsoleSampleClient().Wait(); - // add it to the dictionary under this submodels idShort - OPCClients.Add(URL, client); - } - catch (AggregateException ae) - { - bool cantconnect = false; - ae.Handle((x) => - { - if (x is ServiceResultException) - { - cantconnect = true; - return true; // this exception handled - } - return false; // others not handled, will cause unhandled exception - } - ); - if (cantconnect) - { - // stop processing OPC read because we couldnt connect - // but return true as this shouldn't stop the main loop - Console.WriteLine(ae.Message); - Console.WriteLine("Could not connect to {0} with {1} ...", URL, sm.IdShort); - return true; - } - } - } - else - { - Console.WriteLine("Already connected to OPC UA Server at {0} with {1} ...", URL, sm.IdShort); - } - } - Console.WriteLine("=================================================="); - Console.WriteLine("Read values for {0} from {1} ...", sm.IdShort, URL); - Console.WriteLine("=================================================="); - - // over all SMEs - count = sm.SubmodelElements.Count; - for (j = 0; j < count; j++) - { - var sme = sm.SubmodelElements[j]; - // some preparations for multiple AAS below - int serverNamespaceIdx = 3; //could be gotten directly from the nodeMgr in OPCWrite instead, only pass the string part of the Id - - string AASSubmodel = env[i].AasEnv.AssetAdministrationShells[0].IdShort + "." + sm.IdShort; // for multiple AAS, use something like env.AasEnv.AssetAdministrationShells[i].IdShort; - string serverNodePrefix = string.Format("ns={0};s=AASROOT.{1}", serverNamespaceIdx, AASSubmodel); - string nodePath = Path; // generally starts with Submodel idShort - WalkSubmodelElement(sme, nodePath, serverNodePrefix, client, Namespace); - } - } - } - } - i++; - } - } - if (!initial) - { - changeDataVersion(); - } - return true; } static int countRunScript = 0; @@ -3328,117 +2870,9 @@ public static bool parseJson(SubmodelElementCollection c, JObject o, List ShowAsync() - { - if (ask) - { - message += " (y/n, default y): "; - Console.Write(message); - } - else - { - Console.WriteLine(message); - } - if (ask) - { - try - { - ConsoleKeyInfo result = Console.ReadKey(); - Console.WriteLine(); - return await Task.FromResult((result.KeyChar == 'y') || (result.KeyChar == 'Y') || (result.KeyChar == '\r')); - } - catch - { - // intentionally fall through - } - } - return await Task.FromResult(true); - } } + public enum ExitCode : int { Ok = 0, @@ -3450,7 +2884,6 @@ public enum ExitCode : int public class MySampleServer { - SampleServer server; Task status; DateTime lastEventTime; int serverRunTime = Timeout.Infinite; @@ -3473,13 +2906,11 @@ public void Run() try { exitCode = ExitCode.ErrorServerNotStarted; - ConsoleSampleServer().Wait(); Console.WriteLine("Servers succesfully started. Press Ctrl-C to exit..."); exitCode = ExitCode.ErrorServerRunning; } catch (Exception ex) { - Utils.Trace("ServiceResultException:" + ex.Message); Console.WriteLine("Exception: {0}", ex.Message); exitCode = ExitCode.ErrorServerException; return; @@ -3501,120 +2932,8 @@ public void Run() // wait for timeout or Ctrl-C quitEvent.WaitOne(serverRunTime); - if (server != null) - { - Console.WriteLine("Server stopped. Waiting for exit..."); - - using (SampleServer _server = server) - { - // Stop status thread - server = null; - status.Wait(); - // Stop server and dispose - _server.Stop(); - } - } - exitCode = ExitCode.Ok; } - public static ExitCode ExitCode { get => exitCode; } - - private static void CertificateValidator_CertificateValidation(CertificateValidator validator, CertificateValidationEventArgs e) - { - if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted) - { - e.Accept = autoAccept; - if (autoAccept) - { - } - else - { - } - } - } - - private async Task ConsoleSampleServer() - { - ApplicationInstance.MessageDlg = new ApplicationMessageDlg(); - ApplicationInstance application = new ApplicationInstance(); - - application.ApplicationName = "UA Core Sample Server"; - application.ApplicationType = ApplicationType.Server; - application.ConfigSectionName = Utils.IsRunningOnMono() ? "Opc.Ua.MonoSampleServer" : "Opc.Ua.SampleServer"; - - // load the application configuration. - ApplicationConfiguration config = await application.LoadApplicationConfiguration(true); - - // check the application certificate. - bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(true, 0); - - if (!haveAppCertificate) - { - throw new Exception("Application instance certificate invalid!"); - } - - if (!config.SecurityConfiguration.AutoAcceptUntrustedCertificates) - { - config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); - } - - // start the server. - server = new SampleServer(aasxEnv); - await application.Start(server); - - // start the status thread - status = Task.Run(new Action(StatusThread)); - - // print notification on session events - server.CurrentInstance.SessionManager.SessionActivated += EventStatus; - server.CurrentInstance.SessionManager.SessionClosing += EventStatus; - server.CurrentInstance.SessionManager.SessionCreated += EventStatus; - - } - - private void EventStatus(Opc.Ua.Server.Session session, SessionEventReason reason) - { - lastEventTime = DateTime.UtcNow; - PrintSessionStatus(session, reason.ToString()); - } - - void PrintSessionStatus(Opc.Ua.Server.Session session, string reason, bool lastContact = false) - { - lock (session.DiagnosticsLock) - { - string item = String.Format("{0,9}:{1,20}:", reason, session.SessionDiagnostics.SessionName); - if (lastContact) - { - item += String.Format("Last Event:{0:HH:mm:ss}", session.SessionDiagnostics.ClientLastContactTime.ToLocalTime()); - } - else - { - if (session.Identity != null) - { - item += String.Format(":{0,20}", session.Identity.DisplayName); - } - item += String.Format(":{0}", session.Id); - } - } - } - - private async void StatusThread() - { - while (server != null) - { - if (DateTime.UtcNow - lastEventTime > TimeSpan.FromMilliseconds(6000)) - { - IList sessions = server.CurrentInstance.SessionManager.GetSessions(); - for (int ii = 0; ii < sessions.Count; ii++) - { - Opc.Ua.Server.Session session = sessions[ii]; - PrintSessionStatus(session, "-Status-", true); - } - lastEventTime = DateTime.UtcNow; - } - await Task.Delay(1000); - } - } } } diff --git a/src/AasxServerStandardBib/SampleNodeManager.cs b/src/AasxServerStandardBib/SampleNodeManager.cs deleted file mode 100644 index 8779886d2..000000000 --- a/src/AasxServerStandardBib/SampleNodeManager.cs +++ /dev/null @@ -1,3015 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Xml; -using Opc.Ua.Server; - -namespace Opc.Ua.Sample -{ - /// - /// A node manager for a variety of test data. - /// - public class SampleNodeManager : INodeManager, INodeIdFactory, IDisposable - { - #region Constructors - /// - /// Initializes the node manager. - /// - public SampleNodeManager(IServerInternal server) - { - // save a reference to the server that owns the node manager. - m_server = server; - - // create the default context. - m_systemContext = m_server.DefaultSystemContext.Copy(); - - m_systemContext.SystemHandle = null; - m_systemContext.NodeIdFactory = this; - - // create the table of nodes. - m_predefinedNodes = new NodeIdDictionary(); - m_rootNotifiers = new List(); - m_sampledItems = new List(); - m_minimumSamplingInterval = 100; - } - #endregion - - #region IDisposable Members - /// - /// Frees any unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// An overrideable version of the Dispose. - /// - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - lock (m_lock) - { - Utils.SilentDispose(m_samplingTimer); - m_samplingTimer = null; - - foreach (NodeState node in m_predefinedNodes.Values) - { - Utils.SilentDispose(node); - } - } - } - } - #endregion - - #region INodeIdFactory Members - /// - /// Creates the NodeId for the specified node. - /// - /// The context. - /// The node. - /// The new NodeId. - public virtual NodeId New(ISystemContext context, NodeState node) - { - return node.NodeId; - } - #endregion - - #region Public Properties - /// - /// Acquires the lock on the node manager. - /// - public object Lock - { - get { return m_lock; } - } - #endregion - - #region Protected Members - /// - /// The server that the node manager belongs to. - /// - protected IServerInternal Server - { - get { return m_server; } - } - - /// - /// The default context to use. - /// - public ServerSystemContext SystemContext - { - get { return m_systemContext; } - } - - /// - /// The predefined nodes managed by the node manager. - /// - protected NodeIdDictionary PredefinedNodes - { - get { return m_predefinedNodes; } - } - - /// - /// The root notifiers for the node manager. - /// - protected List RootNotifiers - { - get { return m_rootNotifiers; } - } - - /// - /// Returns true if the namespace for the node id is one of the namespaces managed by the node manager. - /// - /// The node id to check. - /// True if the namespace is one of the nodes. - protected virtual bool IsNodeIdInNamespace(NodeId nodeId) - { - if (NodeId.IsNull(nodeId)) - { - return false; - } - - // quickly exclude nodes that not in the namespace. - for (int ii = 0; ii < m_namespaceIndexes.Length; ii++) - { - if (nodeId.NamespaceIndex == m_namespaceIndexes[ii]) - { - return true; - } - } - - return false; - } - - /// - /// Returns the node if the handle refers to a node managed by this manager. - /// - /// The handle to check. - /// Non-null if the handle belongs to the node manager. - protected virtual NodeState IsHandleInNamespace(object managerHandle) - { - NodeState source = managerHandle as NodeState; - - if (source == null) - { - return null; - } - - if (!IsNodeIdInNamespace(source.NodeId)) - { - return null; - } - - return source; - } - - /// - /// Returns the state object for the specified node if it exists. - /// - public NodeState Find(NodeId nodeId) - { - lock (Lock) - { - NodeState node = null; - - if (!PredefinedNodes.TryGetValue(nodeId, out node)) - { - return null; - } - - return node; - } - } - - /// - /// Creates a new instance and assigns unique identifiers to all children. - /// - /// The operation context. - /// An optional parent identifier. - /// The reference type from the parent. - /// The browse name. - /// The instance to create. - /// The new node id. - public NodeId CreateNode( - ServerSystemContext context, - NodeId parentId, - NodeId referenceTypeId, - QualifiedName browseName, - BaseInstanceState instance) - { - ServerSystemContext contextToUse = (ServerSystemContext)m_systemContext.Copy(context); - - lock (Lock) - { - instance.ReferenceTypeId = referenceTypeId; - - NodeState parent = null; - - if (parentId != null) - { - if (!PredefinedNodes.TryGetValue(parentId, out parent)) - { - throw ServiceResultException.Create( - StatusCodes.BadNodeIdUnknown, - "Cannot find parent with id: {0}", - parentId); - } - - parent.AddChild(instance); - } - - instance.Create(contextToUse, null, browseName, null, true); - AddPredefinedNode(contextToUse, instance); - - return instance.NodeId; - } - } - - /// - /// Deletes a node and all of its children. - /// - public bool DeleteNode( - ServerSystemContext context, - NodeId nodeId) - { - ServerSystemContext contextToUse = m_systemContext.Copy(context); - - bool found = false; - List referencesToRemove = new List(); - - lock (Lock) - { - NodeState node = null; - - if (PredefinedNodes.TryGetValue(nodeId, out node)) - { - RemovePredefinedNode(contextToUse, node, referencesToRemove); - found = true; - } - - RemoveRootNotifier(node); - } - - // must release the lock before removing cross references to other node managers. - if (referencesToRemove.Count > 0) - { - Server.NodeManager.RemoveReferences(referencesToRemove); - } - - return found; - } - #endregion - - #region INodeManager Members - /// - /// Returns the namespaces used by the node manager. - /// - /// - /// All NodeIds exposed by the node manager must be qualified by a namespace URI. This property - /// returns the URIs used by the node manager. In this example all NodeIds use a single URI. - /// - public virtual IEnumerable NamespaceUris - { - get - { - return m_namespaceUris; - } - - protected set - { - if (value != null) - { - m_namespaceUris = new List(value); - } - else - { - m_namespaceUris = new List(); - } - - m_namespaceIndexes = new ushort[m_namespaceUris.Count]; - } - } - - /// - /// Does any initialization required before the address space can be used. - /// - /// - /// The externalReferences is an out parameter that allows the node manager to link to nodes - /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and - /// should have a reference to the root folder node(s) exposed by this node manager. - /// - public virtual void CreateAddressSpace(IDictionary> externalReferences) - { - lock (Lock) - { - // add the uris to the server's namespace table and cache the indexes. - for (int ii = 0; ii < m_namespaceUris.Count; ii++) - { - m_namespaceIndexes[ii] = m_server.NamespaceUris.GetIndexOrAppend(m_namespaceUris[ii]); - } - - LoadPredefinedNodes(m_systemContext, externalReferences); - } - } - - #region CreateAddressSpace Support Functions - /// - /// Loads a node set from a file or resource and addes them to the set of predefined nodes. - /// - public virtual void LoadPredefinedNodes( - ISystemContext context, - Assembly assembly, - string resourcePath, - IDictionary> externalReferences) - { - // load the predefined nodes from an XML document. - NodeStateCollection predefinedNodes = new NodeStateCollection(); - predefinedNodes.LoadFromResource(context, resourcePath, assembly, true); - - // add the predefined nodes to the node manager. - for (int ii = 0; ii < predefinedNodes.Count; ii++) - { - AddPredefinedNode(context, predefinedNodes[ii]); - } - - // ensure the reverse refernces exist. - AddReverseReferences(externalReferences); - } - - /// - /// Loads a node set from a file or resource and addes them to the set of predefined nodes. - /// - protected virtual NodeStateCollection LoadPredefinedNodes(ISystemContext context) - { - return new NodeStateCollection(); - } - - /// - /// Loads a node set from a file or resource and addes them to the set of predefined nodes. - /// - protected virtual void LoadPredefinedNodes( - ISystemContext context, - IDictionary> externalReferences) - { - // load the predefined nodes from an XML document. - NodeStateCollection predefinedNodes = LoadPredefinedNodes(context); - - // add the predefined nodes to the node manager. - for (int ii = 0; ii < predefinedNodes.Count; ii++) - { - AddPredefinedNode(context, predefinedNodes[ii]); - } - - // ensure the reverse refernces exist. - AddReverseReferences(externalReferences); - } - - /// - /// Replaces the generic node with a node specific to the model. - /// - protected virtual NodeState AddBehaviourToPredefinedNode(ISystemContext context, NodeState predefinedNode) - { - BaseObjectState passiveNode = predefinedNode as BaseObjectState; - - if (passiveNode == null) - { - return predefinedNode; - } - - return predefinedNode; - } - - /// - /// Recursively indexes the node and its children. - /// - public virtual void AddPredefinedNode(ISystemContext context, NodeState node) - { - NodeState activeNode = AddBehaviourToPredefinedNode(context, node); - m_predefinedNodes[activeNode.NodeId] = activeNode; - - BaseTypeState type = activeNode as BaseTypeState; - - if (type != null) - { - AddTypesToTypeTree(type); - } - - List children = new List(); - activeNode.GetChildren(context, children); - - for (int ii = 0; ii < children.Count; ii++) - { - AddPredefinedNode(context, children[ii]); - } - } - - /// - /// Recursively indexes the node and its children. - /// - protected virtual void RemovePredefinedNode( - ISystemContext context, - NodeState node, - List referencesToRemove) - { - m_predefinedNodes.Remove(node.NodeId); - node.UpdateChangeMasks(NodeStateChangeMasks.Deleted); - node.ClearChangeMasks(context, false); - OnNodeRemoved(node); - - // remove from the parent. - BaseInstanceState instance = node as BaseInstanceState; - - if (instance != null && instance.Parent != null) - { - instance.Parent.RemoveChild(instance); - } - - // remove children. - List children = new List(); - node.GetChildren(context, children); - - for (int ii = 0; ii < children.Count; ii++) - { - node.RemoveChild(children[ii]); - } - - for (int ii = 0; ii < children.Count; ii++) - { - RemovePredefinedNode(context, children[ii], referencesToRemove); - } - - // remove from type table. - BaseTypeState type = node as BaseTypeState; - - if (type != null) - { - m_server.TypeTree.Remove(type.NodeId); - } - - // remove inverse references. - List references = new List(); - node.GetReferences(context, references); - - for (int ii = 0; ii < references.Count; ii++) - { - IReference reference = references[ii]; - - if (reference.TargetId.IsAbsolute) - { - continue; - } - - LocalReference referenceToRemove = new LocalReference( - (NodeId)reference.TargetId, - reference.ReferenceTypeId, - reference.IsInverse, - node.NodeId); - - referencesToRemove.Add(referenceToRemove); - } - } - - /// - /// Called after a node has been deleted. - /// - protected virtual void OnNodeRemoved(NodeState node) - { - // overridden by the sub-class. - } - - /// - /// Add the node to the set of root notifiers. - /// - protected virtual void AddRootNotifier(NodeState notifier) - { - for (int ii = 0; ii < m_rootNotifiers.Count; ii++) - { - if (Object.ReferenceEquals(notifier, m_rootNotifiers[ii])) - { - return; - } - } - - m_rootNotifiers.Add(notifier); - - // subscribe to existing events. - if (m_server.EventManager != null) - { - IList monitoredItems = m_server.EventManager.GetMonitoredItems(); - - for (int ii = 0; ii < monitoredItems.Count; ii++) - { - if (monitoredItems[ii].MonitoringAllEvents) - { - SubscribeToAllEvents( - SystemContext, - monitoredItems[ii], - true, - notifier); - } - } - } - } - - /// - /// Remove the node from the set of root notifiers. - /// - protected virtual void RemoveRootNotifier(NodeState notifier) - { - for (int ii = 0; ii < m_rootNotifiers.Count; ii++) - { - if (Object.ReferenceEquals(notifier, m_rootNotifiers[ii])) - { - m_rootNotifiers.RemoveAt(ii); - break; - } - } - } - - /// - /// Ensures that all reverse references exist. - /// - /// A list of references to add to external targets. - protected virtual void AddReverseReferences(IDictionary> externalReferences) - { - foreach (NodeState source in m_predefinedNodes.Values) - { - // assign a default value to any variable value. - BaseVariableState variable = source as BaseVariableState; - - if (variable != null && variable.Value == null) - { - variable.Value = TypeInfo.GetDefaultValue(variable.DataType, variable.ValueRank, Server.TypeTree); - } - - // add reference from supertype for type nodes. - - IList references = new List(); - source.GetReferences(SystemContext, references); - - for (int ii = 0; ii < references.Count; ii++) - { - IReference reference = references[ii]; - - // nothing to do with external nodes. - if (reference.TargetId == null || reference.TargetId.IsAbsolute) - { - continue; - } - - NodeId targetId = (NodeId)reference.TargetId; - - // add inverse reference to internal targets. - NodeState target = null; - - if (m_predefinedNodes.TryGetValue(targetId, out target)) - { - if (!target.ReferenceExists(reference.ReferenceTypeId, !reference.IsInverse, source.NodeId)) - { - target.AddReference(reference.ReferenceTypeId, !reference.IsInverse, source.NodeId); - } - - continue; - } - - // check for inverse references to external notifiers. - if (reference.IsInverse && reference.ReferenceTypeId == ReferenceTypeIds.HasNotifier) - { - AddRootNotifier(source); - } - - // nothing more to do for references to nodes managed by this manager. - if (IsNodeIdInNamespace(targetId)) - { - continue; - } - - // add external reference. - AddExternalReference( - targetId, - reference.ReferenceTypeId, - !reference.IsInverse, - source.NodeId, - externalReferences); - } - } - } - - /// - /// Adds an external reference to the dictionary. - /// - protected void AddExternalReference( - NodeId sourceId, - NodeId referenceTypeId, - bool isInverse, - NodeId targetId, - IDictionary> externalReferences) - { - // get list of references to external nodes. - IList referencesToAdd = null; - - if (!externalReferences.TryGetValue(sourceId, out referencesToAdd)) - { - externalReferences[sourceId] = referencesToAdd = new List(); - } - - // add reserve reference from external node. - ReferenceNode referenceToAdd = new ReferenceNode(); - - referenceToAdd.ReferenceTypeId = referenceTypeId; - referenceToAdd.IsInverse = isInverse; - referenceToAdd.TargetId = targetId; - - referencesToAdd.Add(referenceToAdd); - } - - // TODO: MIHO added this - - public void AddExternalReferencePublic( - NodeId sourceId, - NodeId referenceTypeId, - bool isInverse, - NodeId targetId, - IDictionary> externalReferences) - { - if (externalReferences != null) - AddExternalReference(sourceId, referenceTypeId, isInverse, targetId, externalReferences); - } - - /// - /// Recursively adds the types to the type tree. - /// - protected void AddTypesToTypeTree(BaseTypeState type) - { - if (!NodeId.IsNull(type.SuperTypeId)) - { - if (!Server.TypeTree.IsKnown(type.SuperTypeId)) - { - AddTypesToTypeTree(type.SuperTypeId); - } - } - - if (type.NodeClass != NodeClass.ReferenceType) - { - Server.TypeTree.AddSubtype(type.NodeId, type.SuperTypeId); - } - else - { - Server.TypeTree.AddReferenceSubtype(type.NodeId, type.SuperTypeId, type.BrowseName); - } - } - - /// - /// Recursively adds the types to the type tree. - /// - protected void AddTypesToTypeTree(NodeId typeId) - { - BaseTypeState type = Find(typeId) as BaseTypeState; - - if (type == null) - { - return; - } - - AddTypesToTypeTree(type); - } - - /// - /// Finds the specified and checks if it is of the expected type. - /// - /// Returns null if not found or not of the correct type. - public NodeState FindPredefinedNode(NodeId nodeId, Type expectedType) - { - if (nodeId == null) - { - return null; - } - - NodeState node = null; - - if (!PredefinedNodes.TryGetValue(nodeId, out node)) - { - return null; - } - - if (expectedType != null) - { - if (!expectedType.IsInstanceOfType(node)) - { - return null; - } - } - - return node; - } - #endregion - - /// - /// Frees any resources allocated for the address space. - /// - public virtual void DeleteAddressSpace() - { - lock (Lock) - { - m_predefinedNodes.Clear(); - } - } - - /// - /// Returns a unique handle for the node. - /// - /// - /// This must efficiently determine whether the node belongs to the node manager. If it does belong to - /// NodeManager it should return a handle that does not require the NodeId to be validated again when - /// the handle is passed into other methods such as 'Read' or 'Write'. - /// - public virtual object GetManagerHandle(NodeId nodeId) - { - lock (Lock) - { - return GetManagerHandle(m_systemContext, nodeId, null); - } - } - - /// - /// Returns a unique handle for the node. - /// - /// - /// This must efficiently determine whether the node belongs to the node manager. If it does belong to - /// NodeManager it should return a handle that does not require the NodeId to be validated again when - /// the handle is passed into other methods such as 'Read' or 'Write'. - /// - protected virtual object GetManagerHandle(ISystemContext context, NodeId nodeId, IDictionary cache) - { - lock (Lock) - { - // quickly exclude nodes that not in the namespace. - if (!IsNodeIdInNamespace(nodeId)) - { - return null; - } - - // lookup the node. - NodeState node = null; - - if (!m_predefinedNodes.TryGetValue(nodeId, out node)) - { - return null; - } - - return node; - } - } - - /// - /// This method is used to add bi-directional references to nodes from other node managers. - /// - /// - /// The additional references are optional, however, the NodeManager should support them. - /// - public virtual void AddReferences(IDictionary> references) - { - lock (Lock) - { - foreach (KeyValuePair> current in references) - { - // check for valid handle. - NodeState source = GetManagerHandle(m_systemContext, current.Key, null) as NodeState; - - if (source == null) - { - continue; - } - - // add reference to external target. - foreach (IReference reference in current.Value) - { - source.AddReference(reference.ReferenceTypeId, reference.IsInverse, reference.TargetId); - } - } - } - } - - /// - /// This method is used to delete bi-directional references to nodes from other node managers. - /// - public virtual ServiceResult DeleteReference( - object sourceHandle, - NodeId referenceTypeId, - bool isInverse, - ExpandedNodeId targetId, - bool deleteBiDirectional) - { - lock (Lock) - { - // check for valid handle. - NodeState source = IsHandleInNamespace(sourceHandle); - - if (source == null) - { - return StatusCodes.BadNodeIdUnknown; - } - - source.RemoveReference(referenceTypeId, isInverse, targetId); - - if (deleteBiDirectional) - { - // check if the target is also managed by the node manager. - if (!targetId.IsAbsolute) - { - NodeState target = GetManagerHandle(m_systemContext, (NodeId)targetId, null) as NodeState; - - if (target != null) - { - target.RemoveReference(referenceTypeId, !isInverse, source.NodeId); - } - } - } - - return ServiceResult.Good; - } - } - - /// - /// Returns the basic metadata for the node. Returns null if the node does not exist. - /// - /// - /// This method validates any placeholder handle. - /// - public virtual NodeMetadata GetNodeMetadata( - OperationContext context, - object targetHandle, - BrowseResultMask resultMask) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - // check for valid handle. - NodeState target = IsHandleInNamespace(targetHandle); - - if (target == null) - { - return null; - } - - // validate node. - if (!ValidateNode(systemContext, target)) - { - return null; - } - - // read the attributes. - List values = target.ReadAttributes( - systemContext, - Attributes.WriteMask, - Attributes.UserWriteMask, - Attributes.DataType, - Attributes.ValueRank, - Attributes.ArrayDimensions, - Attributes.AccessLevel, - Attributes.UserAccessLevel, - Attributes.EventNotifier, - Attributes.Executable, - Attributes.UserExecutable); - - // construct the metadata object. - - NodeMetadata metadata = new NodeMetadata(target, target.NodeId); - - metadata.NodeClass = target.NodeClass; - metadata.BrowseName = target.BrowseName; - metadata.DisplayName = target.DisplayName; - - if (values[0] != null && values[1] != null) - { - metadata.WriteMask = (AttributeWriteMask)(((uint)values[0]) & ((uint)values[1])); - } - - metadata.DataType = (NodeId)values[2]; - - if (values[3] != null) - { - metadata.ValueRank = (int)values[3]; - } - - metadata.ArrayDimensions = (IList)values[4]; - - if (values[5] != null && values[6] != null) - { - metadata.AccessLevel = (byte)(((byte)values[5]) & ((byte)values[6])); - } - - if (values[7] != null) - { - metadata.EventNotifier = (byte)values[7]; - } - - if (values[8] != null && values[9] != null) - { - metadata.Executable = (((bool)values[8]) && ((bool)values[9])); - } - - // get instance references. - BaseInstanceState instance = target as BaseInstanceState; - - if (instance != null) - { - metadata.TypeDefinition = instance.TypeDefinitionId; - metadata.ModellingRule = instance.ModellingRuleId; - } - - // fill in the common attributes. - return metadata; - } - } - - /// - /// Browses the references from a node managed by the node manager. - /// - /// - /// The continuation point is created for every browse operation and contains the browse parameters. - /// The node manager can store its state information in the Data and Index properties. - /// - public virtual void Browse( - OperationContext context, - ref ContinuationPoint continuationPoint, - IList references) - { - if (continuationPoint == null) throw new ArgumentNullException("continuationPoint"); - if (references == null) throw new ArgumentNullException("references"); - - // check for view. - if (!ViewDescription.IsDefault(continuationPoint.View)) - { - throw new ServiceResultException(StatusCodes.BadViewIdUnknown); - } - - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - // verify that the node exists. - NodeState source = IsHandleInNamespace(continuationPoint.NodeToBrowse); - - if (source == null) - { - throw new ServiceResultException(StatusCodes.BadNodeIdUnknown); - } - - // validate node. - if (!ValidateNode(systemContext, source)) - { - throw new ServiceResultException(StatusCodes.BadNodeIdUnknown); - } - - // check for previous continuation point. - INodeBrowser browser = continuationPoint.Data as INodeBrowser; - - // fetch list of references. - if (browser == null) - { - // create a new browser. - browser = source.CreateBrowser( - systemContext, - continuationPoint.View, - continuationPoint.ReferenceTypeId, - continuationPoint.IncludeSubtypes, - continuationPoint.BrowseDirection, - null, - null, - false); - } - - // apply filters to references. - for (IReference reference = browser.Next(); reference != null; reference = browser.Next()) - { - // create the type definition reference. - ReferenceDescription description = GetReferenceDescription(context, reference, continuationPoint); - - if (description == null) - { - continue; - } - - // check if limit reached. - if (continuationPoint.MaxResultsToReturn != 0 && references.Count >= continuationPoint.MaxResultsToReturn) - { - browser.Push(reference); - continuationPoint.Data = browser; - return; - } - - references.Add(description); - } - - // release the continuation point if all done. - continuationPoint.Dispose(); - continuationPoint = null; - } - } - - #region Browse Support Functions - /// - /// Returns the references for the node that meets the criteria specified. - /// - private ReferenceDescription GetReferenceDescription( - OperationContext context, - IReference reference, - ContinuationPoint continuationPoint) - { - // create the type definition reference. - ReferenceDescription description = new ReferenceDescription(); - - description.NodeId = reference.TargetId; - description.SetReferenceType(continuationPoint.ResultMask, reference.ReferenceTypeId, !reference.IsInverse); - - // do not cache target parameters for remote nodes. - if (reference.TargetId.IsAbsolute) - { - // only return remote references if no node class filter is specified. - if (continuationPoint.NodeClassMask != 0) - { - return null; - } - - return description; - } - - NodeState target = null; - - // check for local reference. - NodeStateReference referenceInfo = reference as NodeStateReference; - - if (referenceInfo != null) - { - target = referenceInfo.Target; - } - - // check for internal reference. - if (target == null) - { - NodeId targetId = (NodeId)reference.TargetId; - - if (IsNodeIdInNamespace(targetId)) - { - if (!PredefinedNodes.TryGetValue(targetId, out target)) - { - target = null; - } - } - } - - // the target may be a reference to a node in another node manager. In these cases - // the target attributes must be fetched by the caller. The Unfiltered flag tells the - // caller to do that. - if (target == null) - { - description.Unfiltered = true; - return description; - } - - // apply node class filter. - if (continuationPoint.NodeClassMask != 0 && ((continuationPoint.NodeClassMask & (uint)target.NodeClass) == 0)) - { - return null; - } - - NodeId typeDefinition = null; - - BaseInstanceState instance = target as BaseInstanceState; - - if (instance != null) - { - typeDefinition = instance.TypeDefinitionId; - } - - // set target attributes. - description.SetTargetAttributes( - continuationPoint.ResultMask, - target.NodeClass, - target.BrowseName, - target.DisplayName, - typeDefinition); - - return description; - } - #endregion - - /// - /// Returns the target of the specified browse path fragment(s). - /// - /// - /// If reference exists but the node manager does not know the browse name it must - /// return the NodeId as an unresolvedTargetIds. The caller will try to check the - /// browse name. - /// - public virtual void TranslateBrowsePath( - OperationContext context, - object sourceHandle, - RelativePathElement relativePath, - IList targetIds, - IList unresolvedTargetIds) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - - lock (Lock) - { - // verify that the node exists. - NodeState source = IsHandleInNamespace(sourceHandle); - - if (source == null) - { - return; - } - - // validate node. - if (!ValidateNode(systemContext, source)) - { - return; - } - - // get list of references that relative path. - INodeBrowser browser = source.CreateBrowser( - systemContext, - null, - relativePath.ReferenceTypeId, - relativePath.IncludeSubtypes, - (relativePath.IsInverse) ? BrowseDirection.Inverse : BrowseDirection.Forward, - relativePath.TargetName, - null, - false); - - // check the browse names. - try - { - for (IReference reference = browser.Next(); reference != null; reference = browser.Next()) - { - // ignore unknown external references. - if (reference.TargetId.IsAbsolute) - { - continue; - } - - NodeState target = null; - - // check for local reference. - NodeStateReference referenceInfo = reference as NodeStateReference; - - if (referenceInfo != null) - { - target = referenceInfo.Target; - } - - if (target == null) - { - NodeId targetId = (NodeId)reference.TargetId; - - // the target may be a reference to a node in another node manager. - if (!IsNodeIdInNamespace(targetId)) - { - unresolvedTargetIds.Add((NodeId)reference.TargetId); - continue; - } - - // look up the target manually. - target = GetManagerHandle(systemContext, targetId, operationCache) as NodeState; - - if (target == null) - { - continue; - } - } - - // check browse name. - if (target.BrowseName == relativePath.TargetName) - { - // ensure duplicate node ids are not added. - if (!targetIds.Contains(reference.TargetId)) - { - targetIds.Add(reference.TargetId); - } - } - } - } - finally - { - browser.Dispose(); - } - } - } - - /// - /// Reads the value for the specified attribute. - /// - public virtual void Read( - OperationContext context, - double maxAge, - IList nodesToRead, - IList values, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - - lock (Lock) - { - for (int ii = 0; ii < nodesToRead.Count; ii++) - { - ReadValueId nodeToRead = nodesToRead[ii]; - - // skip items that have already been processed. - if (nodeToRead.Processed) - { - continue; - } - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, nodeToRead.NodeId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - nodeToRead.Processed = true; - - // create an initial value. - DataValue value = values[ii] = new DataValue(); - - value.Value = null; - value.ServerTimestamp = DateTime.UtcNow; - value.SourceTimestamp = DateTime.MinValue; - value.StatusCode = StatusCodes.Good; - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - errors[ii] = StatusCodes.BadNodeIdUnknown; - - // must validate node in a seperate operation. - ReadWriteOperationState operation = new ReadWriteOperationState(); - - operation.Source = source; - operation.Index = ii; - - nodesToValidate.Add(operation); - - continue; - } - - // read the attribute value. - errors[ii] = source.ReadAttribute( - systemContext, - nodeToRead.AttributeId, - nodeToRead.ParsedIndexRange, - nodeToRead.DataEncoding, - value); - } - - // check for nothing to do. - if (nodesToValidate.Count == 0) - { - return; - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - ReadWriteOperationState operation = nodesToValidate[ii]; - - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - ReadValueId nodeToRead = nodesToRead[operation.Index]; - DataValue value = values[operation.Index]; - - // update the attribute value. - errors[operation.Index] = operation.Source.ReadAttribute( - systemContext, - nodeToRead.AttributeId, - nodeToRead.ParsedIndexRange, - nodeToRead.DataEncoding, - value); - } - } - } - - /// - /// Stores the state of a call method operation. - /// - private struct ReadWriteOperationState - { - public NodeState Source; - public int Index; - } - - /// - /// Verifies that the specified node exists. - /// - protected virtual bool ValidateNode(ServerSystemContext context, NodeState node) - { - // validate node only if required. - if (node.ValidationRequired) - { - return node.Validate(context); - } - - return true; - } - - /// - /// Reads the history for the specified nodes. - /// - public virtual void HistoryRead( - OperationContext context, - HistoryReadDetails details, - TimestampsToReturn timestampsToReturn, - bool releaseContinuationPoints, - IList nodesToRead, - IList results, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - List readsToComplete = new List(); - - lock (Lock) - { - for (int ii = 0; ii < nodesToRead.Count; ii++) - { - HistoryReadValueId nodeToRead = nodesToRead[ii]; - - // skip items that have already been processed. - if (nodeToRead.Processed) - { - continue; - } - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, nodeToRead.NodeId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - nodeToRead.Processed = true; - - // only variables supported. - BaseVariableState variable = source as BaseVariableState; - - if (variable == null) - { - errors[ii] = StatusCodes.BadHistoryOperationUnsupported; - continue; - } - - results[ii] = new HistoryReadResult(); - - ReadWriteOperationState operation = new ReadWriteOperationState(); - - operation.Source = source; - operation.Index = ii; - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - // must validate node in a seperate operation. - errors[ii] = StatusCodes.BadNodeIdUnknown; - nodesToValidate.Add(operation); - continue; - } - - // read the data. - readsToComplete.Add(operation); - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - ReadWriteOperationState operation = nodesToValidate[ii]; - - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - readsToComplete.Add(operation); - } - } - - // reads the data without holding onto the lock. - for (int ii = 0; ii < readsToComplete.Count; ii++) - { - ReadWriteOperationState operation = readsToComplete[ii]; - - errors[operation.Index] = HistoryRead( - systemContext, - operation.Source, - details, - timestampsToReturn, - releaseContinuationPoints, - nodesToRead[operation.Index], - results[operation.Index]); - } - } - - /// - /// Reads the history for a single node which has already been validated. - /// - protected virtual ServiceResult HistoryRead( - ISystemContext context, - NodeState source, - HistoryReadDetails details, - TimestampsToReturn timestampsToReturn, - bool releaseContinuationPoints, - HistoryReadValueId nodesToRead, - HistoryReadResult result) - { - // check for variable. - BaseVariableState variable = source as BaseVariableState; - - if (variable == null) - { - return StatusCodes.BadHistoryOperationUnsupported; - } - - // check for access. - lock (Lock) - { - if ((variable.AccessLevel & AccessLevels.HistoryRead) == 0) - { - return StatusCodes.BadNotReadable; - } - } - - // handle read raw. - ReadRawModifiedDetails readRawDetails = details as ReadRawModifiedDetails; - - if (readRawDetails != null) - { - return HistoryReadRaw( - context, - variable, - readRawDetails, - timestampsToReturn, - releaseContinuationPoints, - nodesToRead, - result); - } - - // handle read processed. - ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails; - - if (readProcessedDetails != null) - { - return HistoryReadProcessed( - context, - variable, - readProcessedDetails, - timestampsToReturn, - releaseContinuationPoints, - nodesToRead, - result); - } - - // handle read processed. - ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails; - - if (readAtTimeDetails != null) - { - return HistoryReadAtTime( - context, - variable, - readAtTimeDetails, - timestampsToReturn, - releaseContinuationPoints, - nodesToRead, - result); - } - - return StatusCodes.BadHistoryOperationUnsupported; - } - - /// - /// Reads the raw history for the variable value. - /// - protected virtual ServiceResult HistoryReadRaw( - ISystemContext context, - BaseVariableState source, - ReadRawModifiedDetails details, - TimestampsToReturn timestampsToReturn, - bool releaseContinuationPoints, - HistoryReadValueId nodeToRead, - HistoryReadResult result) - { - return StatusCodes.BadHistoryOperationUnsupported; - } - - /// - /// Reads the processed history for the variable value. - /// - protected virtual ServiceResult HistoryReadProcessed( - ISystemContext context, - BaseVariableState source, - ReadProcessedDetails details, - TimestampsToReturn timestampsToReturn, - bool releaseContinuationPoints, - HistoryReadValueId nodeToRead, - HistoryReadResult result) - { - return StatusCodes.BadHistoryOperationUnsupported; - } - - /// - /// Reads the history for the variable value. - /// - protected virtual ServiceResult HistoryReadAtTime( - ISystemContext context, - BaseVariableState source, - ReadAtTimeDetails details, - TimestampsToReturn timestampsToReturn, - bool releaseContinuationPoints, - HistoryReadValueId nodeToRead, - HistoryReadResult result) - { - return StatusCodes.BadHistoryOperationUnsupported; - } - - - /// - /// Writes the value for the specified attributes. - /// - public virtual void Write( - OperationContext context, - IList nodesToWrite, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - - lock (Lock) - { - for (int ii = 0; ii < nodesToWrite.Count; ii++) - { - WriteValue nodeToWrite = nodesToWrite[ii]; - - // skip items that have already been processed. - if (nodeToWrite.Processed) - { - continue; - } - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, nodeToWrite.NodeId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - nodeToWrite.Processed = true; - - // index range is not supported. - if (!String.IsNullOrEmpty(nodeToWrite.IndexRange)) - { - errors[ii] = StatusCodes.BadWriteNotSupported; - continue; - } - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - errors[ii] = StatusCodes.BadNodeIdUnknown; - - // must validate node in a seperate operation. - ReadWriteOperationState operation = new ReadWriteOperationState(); - - operation.Source = source; - operation.Index = ii; - - nodesToValidate.Add(operation); - - continue; - } - - // write the attribute value. - errors[ii] = source.WriteAttribute( - systemContext, - nodeToWrite.AttributeId, - nodeToWrite.ParsedIndexRange, - nodeToWrite.Value); - - // updates to source finished - report changes to monitored items. - source.ClearChangeMasks(systemContext, false); - } - - // check for nothing to do. - if (nodesToValidate.Count == 0) - { - return; - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - ReadWriteOperationState operation = nodesToValidate[ii]; - - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - WriteValue nodeToWrite = nodesToWrite[operation.Index]; - - // write the attribute value. - errors[operation.Index] = operation.Source.WriteAttribute( - systemContext, - nodeToWrite.AttributeId, - nodeToWrite.ParsedIndexRange, - nodeToWrite.Value); - - // updates to source finished - report changes to monitored items. - operation.Source.ClearChangeMasks(systemContext, false); - } - } - } - - /// - /// Updates the history for the specified nodes. - /// - public virtual void HistoryUpdate( - OperationContext context, - Type detailsType, - IList nodesToUpdate, - IList results, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - - lock (Lock) - { - for (int ii = 0; ii < nodesToUpdate.Count; ii++) - { - HistoryUpdateDetails nodeToUpdate = nodesToUpdate[ii]; - - // skip items that have already been processed. - if (nodeToUpdate.Processed) - { - continue; - } - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, nodeToUpdate.NodeId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - nodeToUpdate.Processed = true; - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - errors[ii] = StatusCodes.BadNodeIdUnknown; - - // must validate node in a seperate operation. - ReadWriteOperationState operation = new ReadWriteOperationState(); - - operation.Source = source; - operation.Index = ii; - - nodesToValidate.Add(operation); - - continue; - } - - // historical data not available. - errors[ii] = StatusCodes.BadHistoryOperationUnsupported; - } - - // check for nothing to do. - if (nodesToValidate.Count == 0) - { - return; - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - ReadWriteOperationState operation = nodesToValidate[ii]; - - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - // historical data not available. - errors[ii] = StatusCodes.BadHistoryOperationUnsupported; - } - } - } - - /// - /// Calls a method on the specified nodes. - /// - public virtual void Call( - OperationContext context, - IList methodsToCall, - IList results, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - - lock (Lock) - { - for (int ii = 0; ii < methodsToCall.Count; ii++) - { - CallMethodRequest methodToCall = methodsToCall[ii]; - - // skip items that have already been processed. - if (methodToCall.Processed) - { - continue; - } - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, methodToCall.ObjectId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - methodToCall.Processed = true; - - // find the method. - MethodState method = source.FindMethod(systemContext, methodToCall.MethodId); - - if (method == null) - { - // check for loose coupling. - if (source.ReferenceExists(ReferenceTypeIds.HasComponent, false, methodToCall.MethodId)) - { - method = (MethodState)FindPredefinedNode(methodToCall.MethodId, typeof(MethodState)); - } - - if (method == null) - { - errors[ii] = StatusCodes.BadMethodInvalid; - continue; - } - } - - CallMethodResult result = results[ii] = new CallMethodResult(); - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - errors[ii] = StatusCodes.BadNodeIdUnknown; - - // must validate node in a seperate operation. - CallOperationState operation = new CallOperationState(); - - operation.Source = source; - operation.Method = method; - operation.Index = ii; - - nodesToValidate.Add(operation); - - continue; - } - - // call the method. - errors[ii] = Call( - systemContext, - methodToCall, - source, - method, - result); - } - - // check for nothing to do. - if (nodesToValidate.Count == 0) - { - return; - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - CallOperationState operation = nodesToValidate[ii]; - - // validate the object. - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - // call the method. - CallMethodResult result = results[operation.Index]; - - errors[operation.Index] = Call( - systemContext, - methodsToCall[operation.Index], - operation.Source, - operation.Method, - result); - } - } - } - - /// - /// Stores the state of a call method operation. - /// - private struct CallOperationState - { - public NodeState Source; - public MethodState Method; - public int Index; - } - - /// - /// Calls a method on an object. - /// - protected virtual ServiceResult Call( - ISystemContext context, - CallMethodRequest methodToCall, - NodeState source, - MethodState method, - CallMethodResult result) - { - ServerSystemContext systemContext = context as ServerSystemContext; - List argumentErrors = new List(); - VariantCollection outputArguments = new VariantCollection(); - - ServiceResult error = method.Call( - context, - methodToCall.ObjectId, - methodToCall.InputArguments, - argumentErrors, - outputArguments); - - if (ServiceResult.IsBad(error)) - { - return error; - } - - // check for argument errors. - bool argumentsValid = true; - - for (int jj = 0; jj < argumentErrors.Count; jj++) - { - ServiceResult argumentError = argumentErrors[jj]; - - if (argumentError != null) - { - result.InputArgumentResults.Add(argumentError.StatusCode); - - if (ServiceResult.IsBad(argumentError)) - { - argumentsValid = false; - } - } - else - { - result.InputArgumentResults.Add(StatusCodes.Good); - } - - // only fill in diagnostic info if it is requested. - if ((systemContext.OperationContext.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) - { - if (ServiceResult.IsBad(argumentError)) - { - argumentsValid = false; - result.InputArgumentDiagnosticInfos.Add(new DiagnosticInfo(argumentError, systemContext.OperationContext.DiagnosticsMask, false, systemContext.OperationContext.StringTable)); - } - else - { - result.InputArgumentDiagnosticInfos.Add(null); - } - } - } - - // check for validation errors. - if (!argumentsValid) - { - result.StatusCode = StatusCodes.BadInvalidArgument; - return result.StatusCode; - } - - // do not return diagnostics if there are no errors. - result.InputArgumentDiagnosticInfos.Clear(); - - // return output arguments. - result.OutputArguments = outputArguments; - - return ServiceResult.Good; - } - - /// - /// Subscribes or unsubscribes to events produced by the specified source. - /// - /// - /// This method is called when a event subscription is created or deletes. The node manager - /// must start/stop reporting events for the specified object and all objects below it in - /// the notifier hierarchy. - /// - public virtual ServiceResult SubscribeToEvents( - OperationContext context, - object sourceId, - uint subscriptionId, - IEventMonitoredItem monitoredItem, - bool unsubscribe) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - - lock (Lock) - { - // check for valid handle. - NodeState source = IsHandleInNamespace(sourceId); - - if (source == null) - { - return StatusCodes.BadNodeIdInvalid; - } - - // check if the object supports subscritions. - BaseObjectState instance = sourceId as BaseObjectState; - - if (instance == null || instance.EventNotifier != EventNotifiers.SubscribeToEvents) - { - return StatusCodes.BadNotSupported; - } - - MonitoredNode monitoredNode = instance.Handle as MonitoredNode; - - // handle unsubscribe. - if (unsubscribe) - { - if (monitoredNode != null) - { - monitoredNode.UnsubscribeToEvents(systemContext, monitoredItem); - - // do any post processing. - OnUnsubscribeToEvents(systemContext, monitoredNode, monitoredItem); - } - - return ServiceResult.Good; - } - - // subscribe to events. - if (monitoredNode == null) - { - instance.Handle = monitoredNode = new MonitoredNode(m_server, this, source); - } - - monitoredNode.SubscribeToEvents(systemContext, monitoredItem); - - // do any post processing. - OnSubscribeToEvents(systemContext, monitoredNode, monitoredItem); - - return ServiceResult.Good; - } - } - - /// - /// Subscribes or unsubscribes to events produced by all event sources. - /// - /// - /// This method is called when a event subscription is created or deleted. The node - /// manager must start/stop reporting events for all objects that it manages. - /// - public virtual ServiceResult SubscribeToAllEvents( - OperationContext context, - uint subscriptionId, - IEventMonitoredItem monitoredItem, - bool unsubscribe) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - - lock (Lock) - { - // update root notifiers. - for (int ii = 0; ii < m_rootNotifiers.Count; ii++) - { - SubscribeToAllEvents( - systemContext, - monitoredItem, - unsubscribe, - m_rootNotifiers[ii]); - } - - return ServiceResult.Good; - } - } - - /// - /// Subscribes/unsubscribes to all events produced by the specified node. - /// - protected void SubscribeToAllEvents( - ISystemContext systemContext, - IEventMonitoredItem monitoredItem, - bool unsubscribe, - NodeState source) - { - MonitoredNode monitoredNode = source.Handle as MonitoredNode; - - // handle unsubscribe. - if (unsubscribe) - { - if (monitoredNode != null) - { - monitoredNode.UnsubscribeToEvents(systemContext, monitoredItem); - - // do any post processing. - OnUnsubscribeToEvents(systemContext, monitoredNode, monitoredItem); - } - - return; - } - - // subscribe to events. - if (monitoredNode == null) - { - source.Handle = monitoredNode = new MonitoredNode(m_server, this, source); - } - - monitoredNode.SubscribeToEvents(systemContext, monitoredItem); - - // do any post processing. - OnSubscribeToEvents(systemContext, monitoredNode, monitoredItem); - } - - /// - /// Does any processing after a monitored item is subscribed to. - /// - protected virtual void OnSubscribeToEvents( - ISystemContext systemContext, - MonitoredNode monitoredNode, - IEventMonitoredItem monitoredItem) - { - // does nothing. - } - - /// - /// Does any processing after a monitored item is subscribed to. - /// - protected virtual void OnUnsubscribeToEvents( - ISystemContext systemContext, - MonitoredNode monitoredNode, - IEventMonitoredItem monitoredItem) - { - // does nothing. - } - - /// - /// Tells the node manager to refresh any conditions associated with the specified monitored items. - /// - /// - /// This method is called when the condition refresh method is called for a subscription. - /// The node manager must create a refresh event for each condition monitored by the subscription. - /// - public virtual ServiceResult ConditionRefresh( - OperationContext context, - IList monitoredItems) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - for (int ii = 0; ii < monitoredItems.Count; ii++) - { - IEventMonitoredItem monitoredItem = monitoredItems[ii]; - - if (monitoredItem == null) - { - continue; - } - - // check for global subscription. - if (monitoredItem.MonitoringAllEvents) - { - for (int jj = 0; jj < m_rootNotifiers.Count; jj++) - { - MonitoredNode monitoredNode = m_rootNotifiers[jj].Handle as MonitoredNode; - - if (monitoredNode == null) - { - continue; - } - - monitoredNode.ConditionRefresh(systemContext, monitoredItem); - } - } - - // check for subscription to local node. - else - { - NodeState source = IsHandleInNamespace(monitoredItem.ManagerHandle); - - if (source == null) - { - continue; - } - - MonitoredNode monitoredNode = source.Handle as MonitoredNode; - - if (monitoredNode == null) - { - continue; - } - - monitoredNode.ConditionRefresh(systemContext, monitoredItem); - } - } - } - - return ServiceResult.Good; - } - - /// - /// Creates a new set of monitored items for a set of variables. - /// - /// - /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. - /// - public virtual void CreateMonitoredItems( - OperationContext context, - uint subscriptionId, - double publishingInterval, - TimestampsToReturn timestampsToReturn, - IList itemsToCreate, - IList errors, - IList filterErrors, - IList monitoredItems, - ref long globalIdCounter) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - IDictionary operationCache = new NodeIdDictionary(); - List nodesToValidate = new List(); - - lock (Lock) - { - for (int ii = 0; ii < itemsToCreate.Count; ii++) - { - MonitoredItemCreateRequest itemToCreate = itemsToCreate[ii]; - - // skip items that have already been processed. - if (itemToCreate.Processed) - { - continue; - } - - ReadValueId itemToMonitor = itemToCreate.ItemToMonitor; - - // check for valid handle. - NodeState source = GetManagerHandle(systemContext, itemToMonitor.NodeId, operationCache) as NodeState; - - if (source == null) - { - continue; - } - - // owned by this node manager. - itemToCreate.Processed = true; - - // check if the node is ready for reading. - if (source.ValidationRequired) - { - errors[ii] = StatusCodes.BadNodeIdUnknown; - - // must validate node in a seperate operation. - ReadWriteOperationState operation = new ReadWriteOperationState(); - - operation.Source = source; - operation.Index = ii; - - nodesToValidate.Add(operation); - - continue; - } - - MonitoringFilterResult filterError = null; - IMonitoredItem monitoredItem = null; - - errors[ii] = CreateMonitoredItem( - systemContext, - source, - subscriptionId, - publishingInterval, - context.DiagnosticsMask, - timestampsToReturn, - itemToCreate, - ref globalIdCounter, - out filterError, - out monitoredItem); - - // save any filter error details. - filterErrors[ii] = filterError; - - if (ServiceResult.IsBad(errors[ii])) - { - continue; - } - - // save the monitored item. - monitoredItems[ii] = monitoredItem; - } - - // check for nothing to do. - if (nodesToValidate.Count == 0) - { - return; - } - - // validates the nodes (reads values from the underlying data source if required). - for (int ii = 0; ii < nodesToValidate.Count; ii++) - { - ReadWriteOperationState operation = nodesToValidate[ii]; - - // validate the object. - if (!ValidateNode(systemContext, operation.Source)) - { - continue; - } - - MonitoredItemCreateRequest itemToCreate = itemsToCreate[operation.Index]; - - MonitoringFilterResult filterError = null; - IMonitoredItem monitoredItem = null; - - errors[operation.Index] = CreateMonitoredItem( - systemContext, - operation.Source, - subscriptionId, - publishingInterval, - context.DiagnosticsMask, - timestampsToReturn, - itemToCreate, - ref globalIdCounter, - out filterError, - out monitoredItem); - - // save any filter error details. - filterErrors[operation.Index] = filterError; - - if (ServiceResult.IsBad(errors[operation.Index])) - { - continue; - } - - // save the monitored item. - monitoredItems[operation.Index] = monitoredItem; - } - } - } - - /// - /// Validates a data change filter provided by the client. - /// - /// The system context. - /// The node being monitored. - /// The attribute being monitored. - /// The requested monitoring filter. - /// The validated data change filter. - /// The EU range associated with the value if required by the filter. - /// Any error condition. Good if no errors occurred. - protected ServiceResult ValidateDataChangeFilter( - ISystemContext context, - NodeState source, - uint attributeId, - ExtensionObject requestedFilter, - out DataChangeFilter filter, - out Range range) - { - filter = null; - range = null; - - // check for valid filter type. - filter = requestedFilter.Body as DataChangeFilter; - - if (filter == null) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - - // only supported for value attributes. - if (attributeId != Attributes.Value) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - - // only supported for variables. - BaseVariableState variable = source as BaseVariableState; - - if (variable == null) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - - // check the datatype. - if (filter.DeadbandType != (uint)DeadbandType.None) - { - BuiltInType builtInType = TypeInfo.GetBuiltInType(variable.DataType, Server.TypeTree); - - if (!TypeInfo.IsNumericType(builtInType)) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - } - - // validate filter. - ServiceResult error = filter.Validate(); - - if (ServiceResult.IsBad(error)) - { - return error; - } - - if (filter.DeadbandType == (uint)DeadbandType.Percent) - { - BaseVariableState euRange = variable.FindChild(context, BrowseNames.EURange) as BaseVariableState; - - if (euRange == null) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - - range = euRange.Value as Range; - - if (range == null) - { - return StatusCodes.BadMonitoredItemFilterUnsupported; - } - } - - // all good. - return ServiceResult.Good; - } - - /// - /// Creates a new set of monitored items for a set of variables. - /// - /// - /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. - /// - protected virtual ServiceResult CreateMonitoredItem( - ISystemContext context, - NodeState source, - uint subscriptionId, - double publishingInterval, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - MonitoredItemCreateRequest itemToCreate, - ref long globalIdCounter, - out MonitoringFilterResult filterError, - out IMonitoredItem monitoredItem) - { - filterError = null; - monitoredItem = null; - ServiceResult error = null; - - // read initial value. - DataValue initialValue = new DataValue(); - - initialValue.Value = null; - initialValue.ServerTimestamp = DateTime.UtcNow; - initialValue.SourceTimestamp = DateTime.MinValue; - initialValue.StatusCode = StatusCodes.Good; - - error = source.ReadAttribute( - context, - itemToCreate.ItemToMonitor.AttributeId, - itemToCreate.ItemToMonitor.ParsedIndexRange, - itemToCreate.ItemToMonitor.DataEncoding, - initialValue); - - if (ServiceResult.IsBad(error)) - { - if (error.StatusCode == StatusCodes.BadAttributeIdInvalid) - { - return error; - } - - initialValue.StatusCode = error.StatusCode; - error = ServiceResult.Good; - } - - // validate parameters. - MonitoringParameters parameters = itemToCreate.RequestedParameters; - - // validate the data change filter. - DataChangeFilter filter = null; - Range range = null; - - if (!ExtensionObject.IsNull(parameters.Filter)) - { - error = ValidateDataChangeFilter( - context, - source, - itemToCreate.ItemToMonitor.AttributeId, - parameters.Filter, - out filter, - out range); - - if (ServiceResult.IsBad(error)) - { - return error; - } - } - - // create monitored node. - MonitoredNode monitoredNode = source.Handle as MonitoredNode; - - if (monitoredNode == null) - { - source.Handle = monitoredNode = new MonitoredNode(m_server, this, source); - } - - // create a globally unique identifier. - uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); - - // determine the sampling interval. - double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; - - if (samplingInterval < 0) - { - samplingInterval = publishingInterval; - } - - // check if the variable needs to be sampled. - bool samplingRequired = false; - - if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value) - { - BaseVariableState variable = source as BaseVariableState; - - if (variable.MinimumSamplingInterval > 0) - { - samplingInterval = CalculateSamplingInterval(variable, samplingInterval); - samplingRequired = true; - } - } - - // create the item. - DataChangeMonitoredItem datachangeItem = monitoredNode.CreateDataChangeItem( - context, - monitoredItemId, - itemToCreate.ItemToMonitor.AttributeId, - itemToCreate.ItemToMonitor.ParsedIndexRange, - itemToCreate.ItemToMonitor.DataEncoding, - diagnosticsMasks, - timestampsToReturn, - itemToCreate.MonitoringMode, - itemToCreate.RequestedParameters.ClientHandle, - samplingInterval, - itemToCreate.RequestedParameters.QueueSize, - itemToCreate.RequestedParameters.DiscardOldest, - filter, - range, - false); - - if (samplingRequired) - { - CreateSampledItem(samplingInterval, datachangeItem); - } - - // report the initial value. - datachangeItem.QueueValue(initialValue, null); - - // do any post processing. - OnCreateMonitoredItem(context, itemToCreate, monitoredNode, datachangeItem); - - // update monitored item list. - monitoredItem = datachangeItem; - - return ServiceResult.Good; - } - - /// - /// Calculates the sampling interval. - /// - private double CalculateSamplingInterval(BaseVariableState variable, double samplingInterval) - { - if (samplingInterval < variable.MinimumSamplingInterval) - { - samplingInterval = variable.MinimumSamplingInterval; - } - - if ((samplingInterval % m_minimumSamplingInterval) != 0) - { - samplingInterval = Math.Truncate(samplingInterval / m_minimumSamplingInterval); - samplingInterval += 1; - samplingInterval *= m_minimumSamplingInterval; - } - - return samplingInterval; - } - - /// - /// Creates a new sampled item. - /// - private void CreateSampledItem(double samplingInterval, DataChangeMonitoredItem monitoredItem) - { - m_sampledItems.Add(monitoredItem); - - if (m_samplingTimer == null) - { - m_samplingTimer = new Timer(DoSample, null, (int)m_minimumSamplingInterval, (int)m_minimumSamplingInterval); - } - } - - /// - /// Deletes a sampled item. - /// - private void DeleteSampledItem(DataChangeMonitoredItem monitoredItem) - { - for (int ii = 0; ii < m_sampledItems.Count; ii++) - { - if (Object.ReferenceEquals(monitoredItem, m_sampledItems[ii])) - { - m_sampledItems.RemoveAt(ii); - break; - } - } - - if (m_sampledItems.Count == 0) - { - if (m_samplingTimer != null) - { - m_samplingTimer.Dispose(); - m_samplingTimer = null; - } - } - } - - /// - /// Polls each monitored item which requires sample. - /// - private void DoSample(object state) - { - try - { - lock (m_lock) - { - for (int ii = 0; ii < m_sampledItems.Count; ii++) - { - DataChangeMonitoredItem monitoredItem = m_sampledItems[ii]; - - if (monitoredItem.TimeToNextSample < m_minimumSamplingInterval) - { - monitoredItem.ValueChanged(SystemContext); - } - } - } - } - catch (Exception e) - { - Utils.Trace(e, "Unexpected error during diagnostics scan."); - } - } - - /// - /// Does any processing after a monitored item is created. - /// - protected virtual void OnCreateMonitoredItem( - ISystemContext systemContext, - MonitoredItemCreateRequest itemToCreate, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem) - { - // does nothing. - } - - /// - /// Modifies the parameters for a set of monitored items. - /// - public virtual void ModifyMonitoredItems( - OperationContext context, - TimestampsToReturn timestampsToReturn, - IList monitoredItems, - IList itemsToModify, - IList errors, - IList filterErrors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - for (int ii = 0; ii < monitoredItems.Count; ii++) - { - MonitoredItemModifyRequest itemToModify = itemsToModify[ii]; - - // skip items that have already been processed. - if (itemToModify.Processed) - { - continue; - } - - // modify the monitored item. - MonitoringFilterResult filterError = null; - - errors[ii] = ModifyMonitoredItem( - systemContext, - context.DiagnosticsMask, - timestampsToReturn, - monitoredItems[ii], - itemToModify, - out filterError); - - // save any filter error details. - filterErrors[ii] = filterError; - } - } - } - - /// - /// Modifies the parameters for a monitored item. - /// - protected virtual ServiceResult ModifyMonitoredItem( - ISystemContext context, - DiagnosticsMasks diagnosticsMasks, - TimestampsToReturn timestampsToReturn, - IMonitoredItem monitoredItem, - MonitoredItemModifyRequest itemToModify, - out MonitoringFilterResult filterError) - { - filterError = null; - ServiceResult error = null; - - // check for valid handle. - MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; - - if (monitoredNode == null) - { - return ServiceResult.Good; - } - - if (IsHandleInNamespace(monitoredNode.Node) == null) - { - return ServiceResult.Good; - } - - // owned by this node manager. - itemToModify.Processed = true; - - // check for valid monitored item. - DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; - - // validate parameters. - MonitoringParameters parameters = itemToModify.RequestedParameters; - - // validate the data change filter. - DataChangeFilter filter = null; - Range range = null; - - if (!ExtensionObject.IsNull(parameters.Filter)) - { - error = ValidateDataChangeFilter( - context, - monitoredNode.Node, - datachangeItem.AttributeId, - parameters.Filter, - out filter, - out range); - - if (ServiceResult.IsBad(error)) - { - return error; - } - } - - double previousSamplingInterval = datachangeItem.SamplingInterval; - - // check if the variable needs to be sampled. - double samplingInterval = itemToModify.RequestedParameters.SamplingInterval; - - if (datachangeItem.AttributeId == Attributes.Value) - { - BaseVariableState variable = monitoredNode.Node as BaseVariableState; - - if (variable.MinimumSamplingInterval > 0) - { - samplingInterval = CalculateSamplingInterval(variable, samplingInterval); - } - } - - // modify the monitored item parameters. - error = datachangeItem.Modify( - diagnosticsMasks, - timestampsToReturn, - itemToModify.RequestedParameters.ClientHandle, - samplingInterval, - itemToModify.RequestedParameters.QueueSize, - itemToModify.RequestedParameters.DiscardOldest, - filter, - range); - - // do any post processing. - OnModifyMonitoredItem( - context, - itemToModify, - monitoredNode, - datachangeItem, - previousSamplingInterval); - - return ServiceResult.Good; - } - - /// - /// Does any processing after a monitored item is created. - /// - protected virtual void OnModifyMonitoredItem( - ISystemContext systemContext, - MonitoredItemModifyRequest itemToModify, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem, - double previousSamplingInterval) - { - // does nothing. - } - - /// - /// Deletes a set of monitored items. - /// - public virtual void DeleteMonitoredItems( - OperationContext context, - IList monitoredItems, - IList processedItems, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - for (int ii = 0; ii < monitoredItems.Count; ii++) - { - // skip items that have already been processed. - if (processedItems[ii]) - { - continue; - } - - // delete the monitored item. - bool processed = false; - - errors[ii] = DeleteMonitoredItem( - systemContext, - monitoredItems[ii], - out processed); - - // indicate whether it was processed or not. - processedItems[ii] = processed; - } - } - } - - /// - /// Deletes a monitored item. - /// - protected virtual ServiceResult DeleteMonitoredItem( - ISystemContext context, - IMonitoredItem monitoredItem, - out bool processed) - { - processed = false; - - // check for valid handle. - MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; - - if (monitoredNode == null) - { - return ServiceResult.Good; - } - - if (IsHandleInNamespace(monitoredNode.Node) == null) - { - return ServiceResult.Good; - } - - // owned by this node manager. - processed = true; - - // get the source. - NodeState source = monitoredNode.Node; - - // check for valid monitored item. - DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; - - // check if the variable needs to be sampled. - if (datachangeItem.AttributeId == Attributes.Value) - { - BaseVariableState variable = monitoredNode.Node as BaseVariableState; - - if (variable.MinimumSamplingInterval > 0) - { - DeleteSampledItem(datachangeItem); - } - } - - // remove item. - monitoredNode.DeleteItem(datachangeItem); - - // do any post processing. - OnDeleteMonitoredItem(context, monitoredNode, datachangeItem); - - return ServiceResult.Good; - } - - /// - /// Does any processing after a monitored item is deleted. - /// - protected virtual void OnDeleteMonitoredItem( - ISystemContext systemContext, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem) - { - // does nothing. - } - - /// - /// Changes the monitoring mode for a set of monitored items. - /// - public virtual void SetMonitoringMode( - OperationContext context, - MonitoringMode monitoringMode, - IList monitoredItems, - IList processedItems, - IList errors) - { - ServerSystemContext systemContext = m_systemContext.Copy(context); - - lock (Lock) - { - for (int ii = 0; ii < monitoredItems.Count; ii++) - { - // skip items that have already been processed. - if (processedItems[ii]) - { - continue; - } - - // update monitoring mode. - bool processed = false; - - errors[ii] = SetMonitoringMode( - systemContext, - monitoredItems[ii], - monitoringMode, - out processed); - - // indicate whether it was processed or not. - processedItems[ii] = processed; - } - } - } - - /// - /// Changes the monitoring mode for an item. - /// - protected virtual ServiceResult SetMonitoringMode( - ISystemContext context, - IMonitoredItem monitoredItem, - MonitoringMode monitoringMode, - out bool processed) - { - processed = false; - - // check for valid handle. - MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; - - if (monitoredNode == null) - { - return ServiceResult.Good; - } - - if (IsHandleInNamespace(monitoredNode.Node) == null) - { - return ServiceResult.Good; - } - - // owned by this node manager. - processed = true; - - // check for valid monitored item. - DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; - - // update monitoring mode. - MonitoringMode previousMode = datachangeItem.SetMonitoringMode(monitoringMode); - - // need to provide an immediate update after enabling. - if (previousMode == MonitoringMode.Disabled && monitoringMode != MonitoringMode.Disabled) - { - DataValue initialValue = new DataValue(); - - initialValue.Value = null; - initialValue.ServerTimestamp = DateTime.UtcNow; - initialValue.SourceTimestamp = DateTime.MinValue; - initialValue.StatusCode = StatusCodes.Good; - - ServiceResult error = monitoredNode.Node.ReadAttribute( - context, - datachangeItem.AttributeId, - datachangeItem.IndexRange, - datachangeItem.DataEncoding, - initialValue); - - datachangeItem.QueueValue(initialValue, error); - } - - // do any post processing. - OnSetMonitoringMode(context, monitoredNode, datachangeItem, previousMode, monitoringMode); - - return ServiceResult.Good; - } - - /// - /// Does any processing after a monitored item is created. - /// - protected virtual void OnSetMonitoringMode( - ISystemContext systemContext, - MonitoredNode monitoredNode, - DataChangeMonitoredItem monitoredItem, - MonitoringMode previousMode, - MonitoringMode currentMode) - { - // does nothing. - } - - public void TransferMonitoredItems(OperationContext context, bool sendInitialValues, IList monitoredItems, IList processedItems, IList errors) - { - throw new NotImplementedException(); - } - #endregion - - #region Private Fields - private object m_lock = new object(); - private IServerInternal m_server; - private ServerSystemContext m_systemContext; - private IList m_namespaceUris; - private ushort[] m_namespaceIndexes; - private NodeIdDictionary m_predefinedNodes; - private List m_rootNotifiers; - - private Timer m_samplingTimer; - private List m_sampledItems; - private double m_minimumSamplingInterval; - #endregion - } -} diff --git a/src/AasxServerStandardBib/SampleServer.SampleModel.cs b/src/AasxServerStandardBib/SampleServer.SampleModel.cs deleted file mode 100644 index 6f362753e..000000000 --- a/src/AasxServerStandardBib/SampleServer.SampleModel.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - - -namespace AasOpcUaServer -{ - public partial class SampleServer - { - } -} diff --git a/src/AasxServerStandardBib/SampleServer.UserAuthentication.cs b/src/AasxServerStandardBib/SampleServer.UserAuthentication.cs deleted file mode 100644 index 560a183b3..000000000 --- a/src/AasxServerStandardBib/SampleServer.UserAuthentication.cs +++ /dev/null @@ -1,179 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -using System; -using System.Security.Cryptography.X509Certificates; -using Opc.Ua; -using Opc.Ua.Server; -using System.IdentityModel.Selectors; - -namespace AasOpcUaServer -{ - public partial class SampleServer - { - #region User Validation Functions - /// - /// Creates the objects used to validate the user identity tokens supported by the server. - /// - private void CreateUserIdentityValidators(ApplicationConfiguration configuration) - { - for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++) - { - UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii]; - - // create a validator for a certificate token policy. - if (policy.TokenType == UserTokenType.Certificate) - { - // check if user certificate trust lists are specified in configuration. - if (configuration.SecurityConfiguration.TrustedUserCertificates != null && - configuration.SecurityConfiguration.UserIssuerCertificates != null) - { - CertificateValidator certificateValidator = new CertificateValidator(); - certificateValidator.Update(configuration.SecurityConfiguration).Wait(); - certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates, - configuration.SecurityConfiguration.TrustedUserCertificates, - configuration.SecurityConfiguration.RejectedCertificateStore); - - // set custom validator for user certificates. - m_certificateValidator = (X509CertificateValidator)certificateValidator.GetChannelValidator(); - } - } - } - } - - /// - /// Called when a client tries to change its user identity. - /// - private void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args) - { - // check for a WSS token. - IssuedIdentityToken wssToken = args.NewIdentity as IssuedIdentityToken; - - // check for a user name token. - UserNameIdentityToken userNameToken = args.NewIdentity as UserNameIdentityToken; - - if (userNameToken != null) - { - VerifyPassword(userNameToken.UserName, userNameToken.DecryptedPassword); - args.Identity = new UserIdentity(userNameToken); - Utils.Trace("UserName Token Accepted: {0}", args.Identity.DisplayName); - return; - } - - // check for x509 user token. - X509IdentityToken x509Token = args.NewIdentity as X509IdentityToken; - - if (x509Token != null) - { - VerifyCertificate(x509Token.Certificate); - args.Identity = new UserIdentity(x509Token); - Utils.Trace("X509 Token Accepted: {0}", args.Identity.DisplayName); - return; - } - } - - /// - /// Validates the password for a username token. - /// - private void VerifyPassword(string userName, string password) - { - if (String.IsNullOrEmpty(password)) - { - // construct translation object with default text. - TranslationInfo info = new TranslationInfo( - "InvalidPassword", - "en-US", - "Specified password is not valid for user '{0}'.", - userName); - - // create an exception with a vendor defined sub-code. - throw new ServiceResultException(new ServiceResult( - StatusCodes.BadIdentityTokenRejected, - "InvalidPassword", - "http://opcfoundation.org/UA/Sample/", - new LocalizedText(info))); - } - } - - /// - /// Verifies that a certificate user token is trusted. - /// - private void VerifyCertificate(X509Certificate2 certificate) - { - try - { - if (m_certificateValidator != null) - { - m_certificateValidator.Validate(certificate); - } - else - { - CertificateValidator.Validate(certificate); - } - } - catch (Exception e) - { - TranslationInfo info; - StatusCode result = StatusCodes.BadIdentityTokenRejected; - ServiceResultException se = e as ServiceResultException; - if (se != null && se.StatusCode == StatusCodes.BadCertificateUseNotAllowed) - { - info = new TranslationInfo( - "InvalidCertificate", - "en-US", - "'{0}' is an invalid user certificate.", - certificate.Subject); - - result = StatusCodes.BadIdentityTokenInvalid; - } - else - { - // construct translation object with default text. - info = new TranslationInfo( - "UntrustedCertificate", - "en-US", - "'{0}' is not a trusted user certificate.", - certificate.Subject); - } - - // create an exception with a vendor defined sub-code. - throw new ServiceResultException(new ServiceResult( - result, - info.Key, - "http://opcfoundation.org/UA/Sample/", - new LocalizedText(info))); - } - } - #endregion - - #region Private Fields - private X509CertificateValidator m_certificateValidator; - #endregion - } -} diff --git a/src/AasxServerStandardBib/SampleServer.cs b/src/AasxServerStandardBib/SampleServer.cs deleted file mode 100644 index 8b1aa7df4..000000000 --- a/src/AasxServerStandardBib/SampleServer.cs +++ /dev/null @@ -1,209 +0,0 @@ -/* ======================================================================== - * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved. - * - * OPC Foundation MIT License 1.00 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * The complete license agreement can be found here: - * http://opcfoundation.org/License/MIT/1.00/ - * ======================================================================*/ - -#define CUSTOM_NODE_MANAGER - -using System.Collections.Generic; -using System.Diagnostics; -using AdminShellNS; -using Opc.Ua; -using Opc.Ua.Server; - -namespace AasOpcUaServer -{ - /// - /// A class which implements an instance of a UA server. - /// - public partial class SampleServer : StandardServer - { - private AdminShellPackageEnv[] thePackageEnv = null; - private AasxUaServerOptions theServerOptions = null; - - public SampleServer() - : base() - { - } - - public SampleServer(AdminShellPackageEnv[] env, AasxUaServerOptions serverOptions = null) - : base() - { - thePackageEnv = env; - theServerOptions = serverOptions; - } - - #region Overridden Methods - /// - /// Initializes the server before it starts up. - /// - /// - /// This method is called before any startup processing occurs. The sub-class may update the - /// configuration object or do any other application specific startup tasks. - /// - protected override void OnServerStarting(ApplicationConfiguration configuration) - { - Utils.Trace("The server is starting."); - - base.OnServerStarting(configuration); - - // it is up to the application to decide how to validate user identity tokens. - // this function creates validator for X509 identity tokens. - CreateUserIdentityValidators(configuration); - } - - /// - /// Called after the server has been started. - /// - protected override void OnServerStarted(IServerInternal server) - { - base.OnServerStarted(server); - - // request notifications when the user identity is changed. all valid users are accepted by default. - server.SessionManager.ImpersonateUser += new ImpersonateEventHandler(SessionManager_ImpersonateUser); - - } - - /// - /// Cleans up before the server shuts down. - /// - /// - /// This method is called before any shutdown processing occurs. - /// - protected override void OnServerStopping() - { - Debug.WriteLine("The Server is stopping."); - - base.OnServerStopping(); - -#if INCLUDE_Sample - CleanSampleModel(); -#endif - } - -#if CUSTOM_NODE_MANAGER - /// - /// Creates the node managers for the server. - /// - /// - /// This method allows the sub-class create any additional node managers which it uses. The SDK - /// always creates a CoreNodeManager which handles the built-in nodes defined by the specification. - /// Any additional NodeManagers are expected to handle application specific nodes. - /// - /// Applications with small address spaces do not need to create their own NodeManagers and can add any - /// application specific nodes to the CoreNodeManager. Applications should use custom NodeManagers when - /// the structure of the address space is stored in another system or when the address space is too large - /// to keep in memory. - /// - protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration) - { - Debug.WriteLine("Creating the Node Managers."); - - List nodeManagers = new List(); - - // create the custom node managers. - // TODO (MIHO, 2021-01-01): re-implement multi environment UA server again! - var aasnm = new global::AasOpcUaServer.AasModeManager(server, configuration, thePackageEnv, theServerOptions); - nodeManagers.Add(aasnm); - - // create master node manager. - var x = new MasterNodeManager(server, configuration, null, nodeManagers.ToArray()); - - // try to do some fixes - if (x.NodeManagers.Count > 0) - { - var cm = x.NodeManagers[0] as CustomNodeManager2; - } - - // ok - return x; - } -#endif - - /// - /// Loads the non-configurable properties for the application. - /// - /// - /// These properties are exposed by the server but cannot be changed by administrators. - /// - protected override ServerProperties LoadServerProperties() - { - ServerProperties properties = new ServerProperties(); - - properties.ManufacturerName = "OPC Foundation"; - properties.ProductName = "OPC UA SDK Samples"; - properties.ProductUri = "http://opcfoundation.org/UA/Samples/v1.0"; - properties.SoftwareVersion = Utils.GetAssemblySoftwareVersion(); - properties.BuildNumber = Utils.GetAssemblyBuildNumber(); - properties.BuildDate = Utils.GetAssemblyTimestamp(); - - - - - return properties; - } - - /// - /// Initializes the address space after the NodeManagers have started. - /// - /// - /// This method can be used to create any initialization that requires access to node managers. - /// - protected override void OnNodeManagerStarted(IServerInternal server) - { - Debug.WriteLine("The NodeManagers have started."); - - // allow base class processing to happen first. - base.OnNodeManagerStarted(server); - - // adds the sample information models to the core node manager. -#if INCLUDE_Sample - InitializeSampleModel(); -#endif - } - -#if USER_AUTHENTICATION - /// - /// Creates the resource manager for the server. - /// - protected override ResourceManager CreateResourceManager(IServerInternal server, ApplicationConfiguration configuration) - { - ResourceManager resourceManager = new ResourceManager(server, configuration); - - // add some localized strings to the resource manager to demonstrate that localization occurs. - resourceManager.Add("InvalidPassword", "de-DE", "Das Passwort ist nicht gültig für Konto '{0}'."); - resourceManager.Add("InvalidPassword", "es-ES", "La contraseña no es válida para la cuenta de '{0}'."); - - resourceManager.Add("UnexpectedUserTokenError", "fr-FR", "Une erreur inattendue s'est produite lors de la validation utilisateur."); - resourceManager.Add("UnexpectedUserTokenError", "de-DE", "Ein unerwarteter Fehler ist aufgetreten während des Anwenders."); - - return resourceManager; - } -#endif - #endregion - } -} diff --git a/src/AasxServerStandardBib/SecurityClient.cs b/src/AasxServerStandardBib/SecurityClient.cs index 2ba342263..dde5af27d 100644 --- a/src/AasxServerStandardBib/SecurityClient.cs +++ b/src/AasxServerStandardBib/SecurityClient.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IdentityModel.Tokens.Jwt; @@ -13,27 +12,16 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using AasCore.Aas3_0; using AasxRestServerLibrary; -using AasxServer; using AdminShellNS; using Extensions; using IdentityModel; using IdentityModel.Client; using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Security.Cryptography; -using MimeKit.Cryptography; -using Org.BouncyCastle.Crypto; -using System.Runtime.Serialization.Formatters.Binary; using System.Linq; -using Org.BouncyCastle.Asn1.Ocsp; -using System.Threading.Channels; -using System.CommandLine.Parsing; using Microsoft.EntityFrameworkCore; -using static QRCoder.PayloadGenerator; -using Microsoft.AspNetCore.Components; namespace AasxServer { @@ -57,7 +45,8 @@ public static void taskInit() if (System.IO.File.Exists(proxyFile)) { try - { // Open the text file using a stream reader. + { + // Open the text file using a stream reader. using (StreamReader sr = new StreamReader(proxyFile)) { proxyFile = sr.ReadLine(); @@ -79,7 +68,8 @@ public static void taskInit() string username = ""; string password = ""; try - { // Open the text file using a stream reader. + { + // Open the text file using a stream reader. using (StreamReader sr = new StreamReader(proxyFile)) { proxyAddress = sr.ReadLine(); @@ -93,6 +83,7 @@ public static void taskInit() Console.WriteLine(e.Message); error = true; } + if (!error) { Console.WriteLine("Proxy: " + proxyAddress); @@ -111,10 +102,10 @@ public static void taskInit() for (int i = 0; i < aascount; i++) { - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; if (aas.Submodels != null && aas.Submodels.Count > 0) { foreach (var smr in aas.Submodels) @@ -128,7 +119,7 @@ public static void taskInit() countSme = sm.SubmodelElements.Count; for (int iSme = 0; iSme < countSme; iSme++) { - var sme = sm.SubmodelElements[iSme]; + var sme = sm.SubmodelElements[ iSme ]; if (sme is SubmodelElementCollection smec) { var nextTask = new AasxTask(); @@ -139,7 +130,7 @@ public static void taskInit() int countSmec = smec.Value.Count; for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var sme2 = smec.Value[iSmec]; + var sme2 = smec.Value[ iSmec ]; var idShort = sme2.IdShort.ToLower(); switch (idShort) @@ -149,24 +140,28 @@ public static void taskInit() { nextTask.taskType = sme2 as Property; } + break; case "cycletime": if (sme2 is Property) { nextTask.cycleTime = sme2 as Property; } + break; case "cyclecount": if (sme2 is Property) { nextTask.cycleCount = sme2 as Property; } + break; case "nextcycle": if (sme2 is Property) { nextTask.nextCycle = sme2 as Property; } + break; } } @@ -191,7 +186,7 @@ static void runOperations(SubmodelElementCollection smec, int envIndex, DateTime int countSmec = smec.Value.Count; for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var sme2 = smec.Value[iSmec]; + var sme2 = smec.Value[ iSmec ]; if (sme2 is Operation op) { @@ -219,6 +214,7 @@ static void runOperations(SubmodelElementCollection smec, int envIndex, DateTime { operation_get_put(op, envIndex, timeStamp); } + break; } } @@ -250,7 +246,7 @@ static void operation_authenticate(Operation op, int envIndex, DateTime timeStam var inputRef = input.Value; if (!(inputRef is ReferenceElement)) return; - var refElement = Program.env[envIndex].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); + var refElement = Program.env[ envIndex ].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); if (refElement is SubmodelElementCollection re) smec = re; } @@ -258,7 +254,7 @@ static void operation_authenticate(Operation op, int envIndex, DateTime timeStam int countSmec = smec.Value.Count; for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var sme2 = smec.Value[iSmec]; + var sme2 = smec.Value[ iSmec ]; var idShort = sme2.IdShort.ToLower(); switch (idShort) @@ -268,54 +264,63 @@ static void operation_authenticate(Operation op, int envIndex, DateTime timeStam { authType = sme2 as Property; } + break; case "authserverendpoint": if (sme2 is Property) { authServerEndPoint = sme2 as Property; } + break; case "accesstoken": if (sme2 is Property) { accessToken = sme2 as Property; } + break; case "clienttoken": if (sme2 is Property) { clientToken = sme2 as Property; } + break; case "username": if (sme2 is Property) { userName = sme2 as Property; } + break; case "password": if (sme2 is Property) { passWord = sme2 as Property; } + break; case "authservercertificate": if (sme2 is AasCore.Aas3_0.File) { authServerCertificate = sme2 as AasCore.Aas3_0.File; } + break; case "clientcertificate": if (sme2 is AasCore.Aas3_0.File) { clientCertificate = sme2 as AasCore.Aas3_0.File; } + break; case "clientcertificatepassword": if (sme2 is Property) { clientCertificatePassWord = sme2 as Property; } + break; } } @@ -338,10 +343,11 @@ static void operation_authenticate(Operation op, int envIndex, DateTime timeStam } if (createAccessToken(envIndex, authServerEndPoint, authServerCertificate, - clientCertificate, clientCertificatePassWord, - accessToken, clientToken)) + clientCertificate, clientCertificatePassWord, + accessToken, clientToken)) accessToken.SetTimeStamp(timeStamp); } + break; } } @@ -371,9 +377,12 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore Stream s = null; try { - s = AasxServer.Program.env[envIndex].GetLocalStreamFromPackage(authServerCertificate.Value, access: FileAccess.Read); + s = AasxServer.Program.env[ envIndex ].GetLocalStreamFromPackage(authServerCertificate.Value, access: FileAccess.Read); + } + catch + { } - catch { } + if (s == null) { Console.WriteLine("Stream error!"); @@ -395,9 +404,12 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore Stream s2 = null; try { - s2 = AasxServer.Program.env[envIndex].GetLocalStreamFromPackage(clientCertificate.Value, access: FileAccess.Read); + s2 = AasxServer.Program.env[ envIndex ].GetLocalStreamFromPackage(clientCertificate.Value, access: FileAccess.Read); + } + catch + { } - catch { } + if (s2 == null) { Console.WriteLine("Stream error!"); @@ -431,36 +443,38 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore for (int i = 0; i < xc.Count; i++) { xce.MoveNext(); - X509Base64[--j] = Convert.ToBase64String(xce.Current.GetRawCertData()); + X509Base64[ --j ] = Convert.ToBase64String(xce.Current.GetRawCertData()); // X509Base64[--j] = Base64UrlEncoder.Encode(xce.Current.GetRawCertData()); } + x5c = X509Base64; var credential = new X509SigningCredentials(certificate); string clientId = "client.jwt"; string email = ""; string subject = certificate.Subject; - var split = subject.Split(new Char[] { ',' }); - if (split[0] != "") + var split = subject.Split(new Char[] {','}); + if (split[ 0 ] != "") { - var split2 = split[0].Split(new Char[] { '=' }); - if (split2[0] == "E") + var split2 = split[ 0 ].Split(new Char[] {'='}); + if (split2[ 0 ] == "E") { - email = split2[1]; + email = split2[ 1 ]; } } + Console.WriteLine("email: " + email); var now = DateTime.UtcNow; var claimList = new List() - { - new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), - new Claim(JwtClaimTypes.Subject, clientId), - new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), - // OZ - new Claim(JwtClaimTypes.Email, email), - }; + { + new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), + new Claim(JwtClaimTypes.Subject, clientId), + new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), + // OZ + new Claim(JwtClaimTypes.Email, email), + }; if (policy != "") claimList.Add(new Claim("policy", policy, ClaimValueTypes.String)); if (policyRequestedResource != "") @@ -472,7 +486,7 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore now, now.AddMinutes(1), credential) - ; + ; token.Header.Add("x5c", x5c); var tokenHandler = new JwtSecurityTokenHandler(); @@ -488,10 +502,10 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore Scope = "resource1.scope1", ClientAssertion = - { - Type = OidcConstants.ClientAssertionTypes.JwtBearer, - Value = clientLongToken - } + { + Type = OidcConstants.ClientAssertionTypes.JwtBearer, + Value = clientLongToken + } }); }); task.Wait(); @@ -519,14 +533,18 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore { userName = parsed.SelectToken("userName").Value(); } - catch { } + catch + { + } string expires = ""; try { expires = parsed.SelectToken("exp").Value(); } - catch { } + catch + { + } if (userName != "" && expires != "") { @@ -537,13 +555,13 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore var now = DateTime.UtcNow; var claimList = new List() - { - new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), - new Claim(JwtClaimTypes.Subject, clientId), - new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), + { + new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), + new Claim(JwtClaimTypes.Subject, clientId), + new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), - new Claim("userName", userName), - }; + new Claim("userName", userName), + }; if (policy != "") claimList.Add(new Claim("policy", policy, ClaimValueTypes.String)); if (policyRequestedResource != "") @@ -555,7 +573,7 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore now, now.AddDays(1), credential) - ; + ; var tokenHandler = new JwtSecurityTokenHandler(); var t = tokenHandler.WriteToken(token); if (t != null) @@ -569,6 +587,7 @@ static bool createAccessToken(int envIndex, Property authServerEndPoint, AasCore return false; } + static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { // inputVariable reference authentication: collection @@ -621,14 +640,16 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { p = (inputRef as Property); } + if (inputRef is ReferenceElement) { - var refElement = Program.env[envIndex].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); + var refElement = Program.env[ envIndex ].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); if (refElement is SubmodelElementCollection) smec = refElement as SubmodelElementCollection; if (refElement is Submodel) sm = refElement as Submodel; } + switch (inputRef.IdShort.ToLower()) { case "authentication": @@ -663,6 +684,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) break; } } + foreach (var output in op.OutputVariables) { smec = null; @@ -673,14 +695,16 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { p = (outputRef as Property); } + if (outputRef is ReferenceElement) { - var refElement = Program.env[envIndex].AasEnv.FindReferableByReference((outputRef as ReferenceElement).Value); + var refElement = Program.env[ envIndex ].AasEnv.FindReferableByReference((outputRef as ReferenceElement).Value); if (refElement is SubmodelElementCollection) smec = refElement as SubmodelElementCollection; if (refElement is Submodel) sm = refElement as Submodel; } + switch (outputRef.IdShort.ToLower()) { case "lastdiff": @@ -704,7 +728,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) int countSmec = smec.Value.Count; for (int iSmec = 0; iSmec < countSmec; iSmec++) { - var sme2 = smec.Value[iSmec]; + var sme2 = smec.Value[ iSmec ]; var idShort = sme2.IdShort.ToLower(); switch (idShort) @@ -714,54 +738,63 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { authType = sme2 as Property; } + break; case "accesstoken": if (sme2 is Property) { accessToken = sme2 as Property; } + break; case "clienttoken": if (sme2 is Property) { clientToken = sme2 as Property; } + break; case "username": if (sme2 is Property) { userName = sme2 as Property; } + break; case "password": if (sme2 is Property) { passWord = sme2 as Property; } + break; case "authservercertificate": if (sme2 is AasCore.Aas3_0.File) { authServerCertificate = sme2 as AasCore.Aas3_0.File; } + break; case "authserverendpoint": if (sme2 is Property) { authServerEndPoint = sme2 as Property; } + break; case "clientcertificate": if (sme2 is AasCore.Aas3_0.File) { clientCertificate = sme2 as AasCore.Aas3_0.File; } + break; case "clientcertificatepassword": if (sme2 is Property) { clientCertificatePassWord = sme2 as Property; } + break; } } @@ -772,6 +805,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { loopCount = Convert.ToInt32(loop.Value); } + var watch = System.Diagnostics.Stopwatch.StartNew(); for (int l = 0; l < loopCount; l++) @@ -781,11 +815,13 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) loop.Value = l + 1 + ""; loop.SetTimeStamp(timeStamp); } + if (duration != null) { duration.Value = watch.ElapsedMilliseconds + " ms"; duration.TimeStamp = timeStamp; } + Program.signalNewData(0); string requestPath = endPoint.Value; @@ -795,13 +831,13 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) Task task = null; string diffPath = ""; var splitPath = path.Value.Split('/'); - string aasPath = splitPath[0]; + string aasPath = splitPath[ 0 ]; string subPath = ""; int i = 1; string pre = ""; while (i < splitPath.Length) { - subPath += pre + splitPath[i]; + subPath += pre + splitPath[ i ]; pre = "."; i++; } @@ -829,21 +865,22 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { opName = "get"; requestPath = endPoint.Value + "/aas/" + aasPath + - "/submodels/" + splitPath[1] + "/elements"; + "/submodels/" + splitPath[ 1 ] + "/elements"; i = 2; while (i < splitPath.Length) { - requestPath += "/" + splitPath[i]; + requestPath += "/" + splitPath[ i ]; i++; } + requestPath += "/complete"; } else { last = DateTime.Parse(lastDiff.Value).ToUniversalTime(); requestPath = endPoint.Value + - "/diffjson/aas/" + splitPath[0] + - "?path=" + subPath; + "/diffjson/aas/" + splitPath[ 0 ] + + "?path=" + subPath; requestPath += "."; // to avoid wrong data by prefix only requestPath += "&time=" + lastDiff.Value; } @@ -858,6 +895,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) else handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials; } + client = new HttpClient(handler); client.Timeout = TimeSpan.FromSeconds(20); @@ -871,9 +909,9 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) accessToken.Value = ""; if (!createAccessToken(envIndex, authServerEndPoint, authServerCertificate, - clientCertificate, clientCertificatePassWord, - accessToken, clientToken, - "", "")) + clientCertificate, clientCertificatePassWord, + accessToken, clientToken, + "", "")) continue; accessToken.TimeStamp = timeStamp; Console.WriteLine("Create Token1"); @@ -895,11 +933,12 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (status != null) { status.Value = response.StatusCode.ToString() + " ; " + - response.Content.ReadAsStringAsync().Result + " ; " + - "HEAD " + requestPath; - status.TimeStamp= timeStamp; + response.Content.ReadAsStringAsync().Result + " ; " + + "HEAD " + requestPath; + status.TimeStamp = timeStamp; Program.signalNewData(0); } + continue; } @@ -927,13 +966,14 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { clientToken.Value = ""; if (!createAccessToken(envIndex, authServerEndPoint, authServerCertificate, - clientCertificate, clientCertificatePassWord, - accessToken, clientToken, - policy, policyRequestedResource)) + clientCertificate, clientCertificatePassWord, + accessToken, clientToken, + policy, policyRequestedResource)) continue; clientToken.TimeStamp = timeStamp; Console.WriteLine("Create Token2"); } + if (steps.Value.Contains("2")) { client.SetBearerToken(clientToken.Value); @@ -953,11 +993,12 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (status != null) { status.Value = response.StatusCode.ToString() + " ; " + - response.Content.ReadAsStringAsync().Result + " ; " + - "GET " + requestPath; + response.Content.ReadAsStringAsync().Result + " ; " + + "GET " + requestPath; status.TimeStamp = timeStamp; Program.signalNewData(0); } + continue; } } @@ -977,7 +1018,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (elementCollection != null) { JObject parsed = JObject.Parse(json); - foreach (JProperty jp1 in (JToken)parsed) + foreach (JProperty jp1 in (JToken) parsed) { if (jp1.Name == "elem") { @@ -990,6 +1031,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) } } } + if (elementSubmodel != null) { // receiveSubmodel = Newtonsoft.Json.JsonConvert.DeserializeObject( @@ -1006,30 +1048,32 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) continue; receiveSubmodel.Id = elementSubmodel.Id; - var aas = Program.env[envIndex].AasEnv.FindAasWithSubmodelId(elementSubmodel.Id); + var aas = Program.env[ envIndex ].AasEnv.FindAasWithSubmodelId(elementSubmodel.Id); // datastructure update - if (Program.env == null || Program.env[envIndex].AasEnv == null /*|| Program.env[envIndex].AasEnv.Assets == null*/) + if (Program.env == null || Program.env[ envIndex ].AasEnv == null /*|| Program.env[envIndex].AasEnv.Assets == null*/) continue; // add Submodel - var existingSm = Program.env[envIndex].AasEnv.FindSubmodelById(elementSubmodel.Id); + var existingSm = Program.env[ envIndex ].AasEnv.FindSubmodelById(elementSubmodel.Id); if (existingSm != null) - Program.env[envIndex].AasEnv.Submodels.Remove(existingSm); - Program.env[envIndex].AasEnv.Submodels.Add(receiveSubmodel); + Program.env[ envIndex ].AasEnv.Submodels.Remove(existingSm); + Program.env[ envIndex ].AasEnv.Submodels.Add(receiveSubmodel); for (int s = 0; s < aas.Submodels.Count; s++) { - if (aas.Submodels[s].Keys[0].Value == existingSm.Id) + if (aas.Submodels[ s ].Keys[ 0 ].Value == existingSm.Id) { aas.Submodels.RemoveAt(s); break; } } + aas.Submodels.Add(receiveSubmodel.GetModelReference()); continue; } } + if (opName == "getdiff") { // lastDiff.Value = "" + timeStamp.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); @@ -1049,13 +1093,14 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (splitPath.Length < 2) continue; requestPath = endPoint.Value + "/aas/" + aasPath + - "/submodels/" + splitPath[0] + "/elements"; + "/submodels/" + splitPath[ 0 ] + "/elements"; i = 1; while (i < splitPath.Length) { - requestPath += "/" + splitPath[i]; + requestPath += "/" + splitPath[ i ]; i++; } + requestPath += "/complete"; try { @@ -1066,10 +1111,11 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (status != null) { status.Value = response.StatusCode.ToString() + " ; " + - response.Content.ReadAsStringAsync().Result + " ; " + - "GET " + requestPath; + response.Content.ReadAsStringAsync().Result + " ; " + + "GET " + requestPath; Program.signalNewData(0); } + continue; } } @@ -1080,7 +1126,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) json = response.Content.ReadAsStringAsync().Result; JObject parsed = JObject.Parse(json); - foreach (JProperty jp1 in (JToken)parsed) + foreach (JProperty jp1 in (JToken) parsed) { if (jp1.Name == "elem") { @@ -1105,17 +1151,20 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) smc.SetAllParentsAndTimestamps(elementCollection, timeStamp, elementCollection.TimeStampCreate); smc.SetTimeStamp(timeStamp); } + found = true; break; } } } + if (!found && d.mode == "CREATE") { elementCollection.Value.Add(receiveCollection); receiveCollection.SetAllParentsAndTimestamps(elementCollection, timeStamp, timeStamp); receiveCollection.SetTimeStamp(timeStamp); } + break; } } @@ -1143,6 +1192,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) else handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials; } + client = new HttpClient(handler); client.Timeout = TimeSpan.FromSeconds(20); if (accessToken != null) @@ -1183,9 +1233,10 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (status != null) { status.Value = response.StatusCode.ToString() + " ; " + - response.Content.ReadAsStringAsync().Result + " ; " + - "GET " + requestPath; + response.Content.ReadAsStringAsync().Result + " ; " + + "GET " + requestPath; } + error = true; } } @@ -1224,15 +1275,17 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) highDataIndex = Convert.ToInt32(ep.Value); lowDataIndex = highDataIndex + 1; } + if (ep.IdShort == "totalSamples") { totalSamples = Convert.ToInt32(ep.Value); } } } + if (elementCollection.Value.Count == 1) { - if (elementCollection.Value[0] is SubmodelElementCollection smc) + if (elementCollection.Value[ 0 ] is SubmodelElementCollection smc) { if (smc.IdShort == "latestData") { @@ -1247,10 +1300,12 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { ep.Value = highDataIndex.ToString(); } + if (ep.IdShort == "lowDataIndex") { ep.Value = lowDataIndex.ToString(); } + if (ep.IdShort == "totalSamples") { ep.Value = totalSamples.ToString(); @@ -1268,6 +1323,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) error = true; } } + if (error || highDataIndex == -1) { opName = "put"; @@ -1293,7 +1349,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) { if (opName == "putdiff") { - var sme = diffCollection.Value[i]; + var sme = diffCollection.Value[ i ]; if (!(sme is SubmodelElementCollection)) continue; elementCollection = sme as SubmodelElementCollection; @@ -1301,11 +1357,13 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) if (elementCollection.TimeStamp <= last) elementCollection = null; } + if (elementCollection != null) { var j = Jsonization.Serialize.ToJsonObject(elementCollection); json = j.ToJsonString(); } + if (elementSubmodel != null) { var j = Jsonization.Serialize.ToJsonObject(elementSubmodel); @@ -1315,10 +1373,11 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) catch { statusValue = "error PUTDIFF index: " + i + " old " + count + - " new " + diffCollection.Value.Count; + " new " + diffCollection.Value.Count; Console.WriteLine(statusValue); error = true; } + if (json != "") { try @@ -1331,8 +1390,8 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) response = await client.PutAsync( requestPath + diffPath, content); }); - } else - if (opName == "putdiff") + } + else if (opName == "putdiff") { task = Task.Run(async () => { @@ -1340,23 +1399,27 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) requestPath, content); }); } + task.Wait(); } catch { error = true; } + if (error || !response.IsSuccessStatusCode) { if (response != null) { statusValue = response.StatusCode.ToString() + " ; " + - response.Content.ReadAsStringAsync().Result + " ; " + - "PUT " + requestPath; + response.Content.ReadAsStringAsync().Result + " ; " + + "PUT " + requestPath; } + error = true; } } + if (error) { if (status != null) @@ -1364,6 +1427,7 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) status.Value = statusValue; Program.signalNewData(0); } + continue; } } @@ -1372,19 +1436,23 @@ static void operation_get_put(Operation op, int envIndex, DateTime timeStamp) lastDiff.Value = "" + timeStamp.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); } } + if (loop != null) { loop.Value = loopCount + ""; loop.TimeStamp = timeStamp; } + watch.Stop(); if (duration != null) { duration.Value = watch.ElapsedMilliseconds + " ms"; duration.TimeStamp = timeStamp; } + Program.signalNewData(2); // new tree, nodes opened } + static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) { // inputVariable reference collection: collection @@ -1395,6 +1463,7 @@ static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) { return; } + SubmodelElementCollection collection = null; Property limit = null; Property prefix = null; @@ -1410,12 +1479,14 @@ static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) { p = (inputRef as Property); } + if (inputRef is ReferenceElement) { - var refElement = Program.env[envIndex].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); + var refElement = Program.env[ envIndex ].AasEnv.FindReferableByReference((inputRef as ReferenceElement).Value); if (refElement is SubmodelElementCollection) smec = refElement as SubmodelElementCollection; } + switch (inputRef.IdShort.ToLower()) { case "collection": @@ -1432,6 +1503,7 @@ static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) break; } } + if (collection == null || limit == null || prefix == null) return; @@ -1443,19 +1515,20 @@ static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) int i = 0; while (i < collection.Value.Count) { - if (pre == collection.Value[i].IdShort.Substring(0, pre.Length)) + if (pre == collection.Value[ i ].IdShort.Substring(0, pre.Length)) preCount++; i++; } + i = 0; while (preCount > count && i < collection.Value.Count) { - if (pre == collection.Value[i].IdShort.Substring(0, pre.Length)) + if (pre == collection.Value[ i ].IdShort.Substring(0, pre.Length)) { - IReferable r = collection.Value[i]; + IReferable r = collection.Value[ i ]; var sm = r.GetParentSubmodel(); AasxRestServerLibrary.AasxRestServer.TestResource.eventMessage.add( - r, "Remove", sm, (ulong)timeStamp.Ticks); + r, "Remove", sm, (ulong) timeStamp.Ticks); collection.Value.RemoveAt(i); preCount--; } @@ -1468,6 +1541,7 @@ static void operation_limitCount(Operation op, int envIndex, DateTime timeStamp) catch { } + Program.signalNewData(1); } @@ -1519,6 +1593,7 @@ static string cleanupIdShort(String text) public static string hashBOM = ""; public static long logCount = 0; public static long logCountModulo = 30; + public static bool createCfpTree(int envIndex, DateTime timeStamp) { bool changed = false; @@ -1540,10 +1615,10 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) for (int i = 0; i < aascount; i++) { - env = AasxServer.Program.env[i]; + env = AasxServer.Program.env[ i ]; if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; // if (aas.IdShort != "ZveiControlCabinetAas - EXTERNAL") // continue; @@ -1553,15 +1628,29 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) // foreach (var smr in aas.Submodels) for (int j = 0; j < aas.Submodels.Count; j++) { - var smr = aas.Submodels[j]; + var smr = aas.Submodels[ j ]; var sm = env.AasEnv.FindSubmodel(smr); if (sm != null && sm.IdShort != null) { if (sm.IdShort.Contains("BillOfMaterial")) { - if (sm.Extensions != null && sm.Extensions.Count != 0 && sm.Extensions[0].Name == "endpoint") + if (sm.Extensions != null && sm.Extensions.Count != 0 && sm.Extensions[ 0 ].Name == "endpoint") { - var requestPath = sm.Extensions[0].Value; + var requestPath = sm.Extensions[ 0 ].Value; + + string queryPara = ""; + string userPW = ""; + string urlEdcWrapper = ""; + string replace = ""; + if (AasxCredentials.get(cs.credentials, requestPath, out queryPara, out userPW, out urlEdcWrapper, out replace)) + { + if (replace != "") + requestPath = replace; + if (queryPara != "") + queryPara = "?" + queryPara; + if (urlEdcWrapper != "") + requestPath = urlEdcWrapper; + } var handler = new HttpClientHandler(); if (!requestPath.Contains("localhost")) @@ -1574,28 +1663,16 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) var client = new HttpClient(handler); + if (userPW != "") + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", userPW); string clientToken = ""; - if (sm.Extensions != null && sm.Extensions.Count > 1 && sm.Extensions[1].Name == "clientToken") - clientToken = sm.Extensions[1].Value; + if (sm.Extensions != null && sm.Extensions.Count > 1 && sm.Extensions[ 1 ].Name == "clientToken") + clientToken = sm.Extensions[ 1 ].Value; if (clientToken != "") client.SetBearerToken(clientToken); - string queryPara = ""; - string userPW = ""; - string urlEdcWrapper = ""; - string replace = ""; client.DefaultRequestHeaders.Clear(); - if (AasxCredentials.get(cs.credentials, requestPath, out queryPara, out userPW, out urlEdcWrapper, out replace)) - { - if (replace != "") - requestPath = replace; - if (queryPara != "") - queryPara = "?" + queryPara; - if (userPW != "") - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", userPW); - if (urlEdcWrapper != "") - requestPath = urlEdcWrapper; - } + bool success = false; HttpResponseMessage response = new HttpResponseMessage(); try @@ -1604,10 +1681,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) if (logCount % logCountModulo == 0) Console.WriteLine("GET Submodel " + requestPath); client.Timeout = TimeSpan.FromSeconds(3); - var task1 = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + var task1 = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task1.Wait(); if (response.IsSuccessStatusCode) { @@ -1633,6 +1707,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) { success = false; } + if (!success) { if (sm.IdShort != "BillOfMaterial - NO ACCESS") @@ -1647,10 +1722,12 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) env.AasEnv.Submodels.Remove(sm); env.AasEnv.Submodels.Add(newsm); } + Console.WriteLine("NO ACCESS: aas " + aas.IdShort + " sm " + sm.IdShort); cfpValid = false; } } + break; } } @@ -1667,10 +1744,10 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) // Collect data from all AAS into cfpNode(s) for (int i = 0; i < aascount; i++) { - env = AasxServer.Program.env[i]; + env = AasxServer.Program.env[ i ]; if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; //var assetId = aas.assetRef.Keys[0].Value; var assetId = aas.AssetInformation.GlobalAssetId; @@ -1695,6 +1772,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) Console.WriteLine("NO ACCESS: aas " + aas.IdShort + " sm " + sm.IdShort); cfpValid = false; } + if (sm.SubmodelElements != null) { foreach (var v in sm.SubmodelElements) @@ -1702,7 +1780,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) if (v is SubmodelElementCollection c) { if (c.IdShort.Contains("FootprintInformationModule") - || c.IdShort.Contains("FootprintInformationCombination")) + || c.IdShort.Contains("FootprintInformationCombination")) { string lifeCyclePhase = ""; Property co2eq = null; @@ -1718,6 +1796,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) break; } } + switch (lifeCyclePhase) { case "Cradle-to-gate": @@ -1726,11 +1805,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.cradleToGateModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.cradleToGateCombination = co2eq; } + break; case "Production": if (c.IdShort.Contains("FootprintInformationModule")) @@ -1738,11 +1819,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.productionModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.productionCombination = co2eq; } + break; case "Distribution": if (c.IdShort.Contains("FootprintInformationModule")) @@ -1750,11 +1833,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.distributionModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.distributionCombination = co2eq; } + break; } } @@ -1762,6 +1847,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + // ZVEI Level 2 if (sm.IdShort.Contains("CarbonFootprint")) { @@ -1770,6 +1856,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) Console.WriteLine("NO ACCESS: aas " + aas.IdShort + " sm " + sm.IdShort); cfpValid = false; } + if (sm.SubmodelElements != null) { foreach (var v in sm.SubmodelElements) @@ -1793,6 +1880,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) break; } } + switch (lifeCyclePhase) { case "Cradle-to-gate": @@ -1802,11 +1890,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.cradleToGateModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.cradleToGateCombination = co2eq; } + break; case "Production": case "A3": @@ -1816,11 +1906,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.productionModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.productionCombination = co2eq; } + break; case "Distribution": case "A2": @@ -1830,11 +1922,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) co2eq.Value = co2eq.Value.Replace(",", "."); cfp.distributionModule = co2eq; } + if (c.IdShort.Contains("FootprintInformationCombination")) { co2eq.Value = co2eq.Value.Replace(",", "."); cfp.distributionCombination = co2eq; } + break; } } @@ -1842,6 +1936,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + if (sm.IdShort.Contains("BillOfMaterial")) { if (sm.IdShort.Contains(" - NO ACCESS")) @@ -1849,6 +1944,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) Console.WriteLine("NO ACCESS: aas " + aas.IdShort + " sm " + sm.IdShort); cfpValid = false; } + if (sm.SubmodelElements != null) { cfp.bomTimestamp = sm.TimeStampTree; @@ -1872,10 +1968,12 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + // assetBOM.Add(assetId, bom); cfp.bom = bom; } } + if (sm.IdShort.Contains("TechnicalData") && sm.SubmodelElements != null) { foreach (var v in sm.SubmodelElements) @@ -1898,6 +1996,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + if (sm.IdShort.Contains("Nameplate") && sm.SubmodelElements != null) { foreach (var v in sm.SubmodelElements) @@ -1916,12 +2015,14 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) s = ls.Text; break; //english has priority over German } + if (ls.Language.ToLower() == "de") { if (s != null) s = ls.Text; } } + if (s != null) cfp.productDesignation = s; } @@ -1929,6 +2030,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + // Weight if (sm.IdShort.Contains("WeightInformation")) { @@ -1937,6 +2039,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) Console.WriteLine("NO ACCESS: aas " + aas.IdShort + " sm " + sm.IdShort); cfpValid = false; } + if (sm.SubmodelElements != null) { foreach (var v in sm.SubmodelElements) @@ -1944,7 +2047,7 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) if (v is SubmodelElementCollection c) { if (c.IdShort.Contains("WeightInformationModule") - || c.IdShort.Contains("WeightInformationCombination")) + || c.IdShort.Contains("WeightInformationCombination")) { foreach (var v2 in c.Value) { @@ -1956,11 +2059,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) cfp.weightModule = v2 as Property; cfp.weightModule.Value = cfp.weightModule.Value.Replace(",", "."); } + if (c.IdShort.Contains("WeightInformationCombination")) { cfp.weightCombination = v2 as Property; cfp.weightCombination.Value = cfp.weightCombination.Value.Replace(",", "."); } + break; } } @@ -1972,10 +2077,12 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) } } } + if (!assetCfp.ContainsKey(assetId)) { assetCfp.Add(assetId, cfp); } + /* if (i == envIndex) { @@ -1985,12 +2092,13 @@ public static bool createCfpTree(int envIndex, DateTime timeStamp) if (aas.IdShort == "ZveiControlCabinetAas - EXTERNAL") { root = cfp; - if(!Program.showWeight && root.cradleToGateCombination != null) + if (!Program.showWeight && root.cradleToGateCombination != null) { //TODO: elements need proper deep clone method implemented within AAS metamodel classes if (asbuilt_total == null) asbuilt_total = new String(root.cradleToGateCombination.Value); } + if (Program.showWeight && root.weightCombination != null) { //TODO: elements need proper deep clone method implemented within AAS metamodel classes @@ -2062,8 +2170,10 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime { node.cradleToGateCombination.Value = node.cradleToGateModule.Value; } + node.cradleToGateCombination.SetTimeStamp(timeStamp); } + if (node.productionCombination != null) { node.productionCombination.Value = "0.0"; @@ -2071,8 +2181,10 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime { node.productionCombination.Value = node.productionModule.Value; } + node.productionCombination.SetTimeStamp(timeStamp); } + if (node.distributionCombination != null) { node.distributionCombination.Value = "0.0"; @@ -2080,8 +2192,10 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime { node.distributionCombination.Value = node.distributionModule.Value; } + node.distributionCombination.SetTimeStamp(timeStamp); } + if (node.weightCombination != null) { node.weightCombination.Value = "0.0"; @@ -2089,9 +2203,11 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime { node.weightCombination.Value = node.weightModule.Value; } + node.weightCombination.SetTimeStamp(timeStamp); } } + // move up, if all children iterated if (node.iChild == node.children.Count) { @@ -2102,7 +2218,7 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime } else { - parent = stack[sp]; + parent = stack[ sp ]; if (parent.cradleToGateCombination != null) { Property p = node.cradleToGateModule; @@ -2120,9 +2236,12 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime parent.cradleToGateCombination.Value = value1.ToString(CultureInfo.InvariantCulture); parent.cradleToGateCombination.SetTimeStamp(timeStamp); } - catch { } + catch + { + } } } + if (parent.productionCombination != null) { Property p = node.productionModule; @@ -2140,9 +2259,12 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime parent.productionCombination.Value = value1.ToString(CultureInfo.InvariantCulture); parent.productionCombination.SetTimeStamp(timeStamp); } - catch { } + catch + { + } } } + if (parent.distributionCombination != null) { Property p = node.distributionModule; @@ -2160,9 +2282,12 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime parent.distributionCombination.Value = value1.ToString(CultureInfo.InvariantCulture); parent.distributionCombination.SetTimeStamp(timeStamp); } - catch { } + catch + { + } } } + if (parent.weightCombination != null) { Property p = node.weightModule; @@ -2180,11 +2305,14 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime parent.weightCombination.Value = value1.ToString(CultureInfo.InvariantCulture); parent.weightCombination.SetTimeStamp(timeStamp); } - catch { } + catch + { + } } } + parent = null; - node = stack[sp]; + node = stack[ sp ]; stack.RemoveAt(sp); sp--; } @@ -2194,7 +2322,7 @@ public static void operation_calculate_cfp(Operation op, int envIndex, DateTime // Interate children stack.Add(node); sp++; - node = node.children[node.iChild++]; + node = node.children[ node.iChild++ ]; } } @@ -2216,7 +2344,7 @@ static void saveAASXtoTemp() { if (!Program.withDb) { - string fn = Program.envFileName[envi]; + string fn = Program.envFileName[ envi ]; if (fn != null && fn != "") { @@ -2226,14 +2354,15 @@ static void saveAASXtoTemp() lock (Program.changeAasxFile) { Console.WriteLine("SAVE TEMP: " + fn); - Program.env[envi].SaveAs("./temp/" + fn, true); + Program.env[ envi ].SaveAs("./temp/" + fn, true); DateTime timeStamp = DateTime.Now; - foreach (var submodel in Program.env[envi].AasEnv.Submodels) + foreach (var submodel in Program.env[ envi ].AasEnv.Submodels) { submodel.TimeStampCreate = timeStamp; submodel.SetTimeStamp(timeStamp); submodel.SetAllParents(timeStamp); } + newData = true; } } @@ -2241,14 +2370,14 @@ static void saveAASXtoTemp() } else { - if (Program.env[envi] != null && Program.env[envi].getWrite()) + if (Program.env[ envi ] != null && Program.env[ envi ].getWrite()) { lock (Program.changeAasxFile) { - var aasList = Program.env[envi].AasEnv.AssetAdministrationShells; + var aasList = Program.env[ envi ].AasEnv.AssetAdministrationShells; var aasIds = aasList.Select(x => x.Id).ToList(); - var submodelList = Program.env[envi].AasEnv.Submodels; + var submodelList = Program.env[ envi ].AasEnv.Submodels; var submodelIds = submodelList.Select(x => x.Id).ToList(); Dictionary aasToDeleteAASXNumsDic; @@ -2276,25 +2405,31 @@ static void saveAASXtoTemp() long assxNum = 0; if (aasToDeleteAASXNumsDic.ContainsKey(aas.Id)) { - assxNum = aasToDeleteAASXNumsDic[aas.Id]; + assxNum = aasToDeleteAASXNumsDic[ aas.Id ]; } - VisitorAASX.LoadAASInDB(db, aas, assxNum, Program.env[envi]); + + VisitorAASX.LoadAASInDB(db, aas, assxNum, Program.env[ envi ]); } + db.SaveChanges(); } + //Program.saveEnv(envi); - Program.env[envi].setWrite(false); + Program.env[ envi ].setWrite(false); newData = true; } } } + envi++; } + if (newData) Program.signalNewData(0); } static Thread tasksThread; + public static void tasksSamplingLoop() { while (true) @@ -2325,7 +2460,7 @@ public static void tasksCyclic() bool taskRun = false; for (int i = 0; i < taskList.Count; i++) { - var t = taskList[i]; + var t = taskList[ i ]; if (t.taskType?.Value.ToLower() == "cyclic") { if (t.nextExecution > timeStamp) @@ -2337,20 +2472,23 @@ public static void tasksCyclic() t.cycleCount.Value = (Convert.ToInt32(t.cycleCount.Value) + 1).ToString(); t.cycleCount.SetTimeStamp(timeStamp); } + t.nextExecution = timeStamp.AddMilliseconds(Convert.ToInt32(t.cycleTime.Value)); if (t.nextCycle != null) { t.nextCycle.Value = t.nextExecution.ToString(); t.nextCycle.SetTimeStamp(timeStamp); } + Program.signalNewData(0); runOperations(t.def, t.envIndex, timeStamp); taskRun = true; } } + if (taskRun) System.GC.Collect(); } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/Services/AdminShellPackageEnvironmentService.cs b/src/AasxServerStandardBib/Services/AdminShellPackageEnvironmentService.cs index 8e3eb5d7a..e38f26265 100644 --- a/src/AasxServerStandardBib/Services/AdminShellPackageEnvironmentService.cs +++ b/src/AasxServerStandardBib/Services/AdminShellPackageEnvironmentService.cs @@ -1,7 +1,8 @@ /* Copyright (c) 2019-2023 Fraunhofer IOSB-INA Lemgo, -    eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft -    zur Foerderung der angewandten Forschung e.V. +eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft +zur Foerderung der angewandten Forschung e.V. */ + using AasxServer; using AasxServerStandardBib.Exceptions; using AasxServerStandardBib.Interfaces; @@ -39,10 +40,10 @@ private bool EmptyPackageAvailable(out int emptyPackageIndex) for (int envi = 0; envi < _packages.Length; envi++) { - if (_packages[envi] == null) + if (_packages[ envi ] == null) { emptyPackageIndex = envi; - _packages[emptyPackageIndex] = new AdminShellPackageEnv(); + _packages[ emptyPackageIndex ] = new AdminShellPackageEnv(); return true; } } @@ -52,23 +53,23 @@ private bool EmptyPackageAvailable(out int emptyPackageIndex) public void setWrite(int packageIndex, bool status) { - _packages[packageIndex].setWrite(status); + _packages[ packageIndex ].setWrite(status); } #endregion #region AssetAdministrationShell + public IAssetAdministrationShell CreateAssetAdministrationShell(IAssetAdministrationShell body) { if (EmptyPackageAvailable(out int emptyPackageIndex)) { - - _packages[emptyPackageIndex].AasEnv.AssetAdministrationShells.Add(body); + _packages[ emptyPackageIndex ].AasEnv.AssetAdministrationShells.Add(body); var timeStamp = DateTime.UtcNow; body.TimeStampCreate = timeStamp; body.SetTimeStamp(timeStamp); Program.signalNewData(2); - return _packages[emptyPackageIndex].AasEnv.AssetAdministrationShells[0]; //Considering it is the first AAS being added to empty package. + return _packages[ emptyPackageIndex ].AasEnv.AssetAdministrationShells[ 0 ]; //Considering it is the first AAS being added to empty package. } else { @@ -80,15 +81,15 @@ public void DeleteAssetAdministrationShell(int packageIndex, IAssetAdministratio { if (aas != null && packageIndex != -1) { - bool deleted = (bool)(_packages[packageIndex].AasEnv?.AssetAdministrationShells.Remove(aas)); + bool deleted = (bool) (_packages[ packageIndex ].AasEnv?.AssetAdministrationShells.Remove(aas)); if (deleted) { _logger.LogDebug($"Deleted Asset Administration Shell with id {aas.Id}"); //if no more shells in the environment, then remove the environment // TODO (jtikekar, 2023-09-04): what about submodels and concept descriptions for the same environment - if (_packages[packageIndex].AasEnv.AssetAdministrationShells.Count == 0) + if (_packages[ packageIndex ].AasEnv.AssetAdministrationShells.Count == 0) { - _packages[packageIndex] = null; + _packages[ packageIndex ] = null; } Program.signalNewData(2); @@ -140,7 +141,8 @@ public bool IsAssetAdministrationShellPresent(string aasIdentifier) private bool IsAssetAdministrationShellPresent(string aasIdentifier, out IAssetAdministrationShell output, out int packageIndex) { - output = null; packageIndex = -1; + output = null; + packageIndex = -1; Program.loadPackageForAas(aasIdentifier, out output, out packageIndex); @@ -170,9 +172,9 @@ public void UpdateAssetAdministrationShellById(IAssetAdministrationShell body, s var aas = GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); if (aas != null && packageIndex != -1) { - var aasIndex = _packages[packageIndex].AasEnv.AssetAdministrationShells.IndexOf(aas); - _packages[packageIndex].AasEnv.AssetAdministrationShells.Remove(aas); - _packages[packageIndex].AasEnv.AssetAdministrationShells.Insert(aasIndex, body); + var aasIndex = _packages[ packageIndex ].AasEnv.AssetAdministrationShells.IndexOf(aas); + _packages[ packageIndex ].AasEnv.AssetAdministrationShells.Remove(aas); + _packages[ packageIndex ].AasEnv.AssetAdministrationShells.Insert(aasIndex, body); var timeStamp = DateTime.UtcNow; body.TimeStampCreate = timeStamp; body.SetTimeStamp(timeStamp); @@ -184,20 +186,21 @@ public void UpdateAssetAdministrationShellById(IAssetAdministrationShell body, s public void DeleteAssetInformationThumbnail(int packageIndex, IResource defaultThumbnail) { - _packages[packageIndex].DeleteAssetInformationThumbnail(defaultThumbnail); + _packages[ packageIndex ].DeleteAssetInformationThumbnail(defaultThumbnail); Program.signalNewData(0); } public Stream GetAssetInformationThumbnail(int packageIndex) { - return _packages[packageIndex].GetLocalThumbnailStream(); + return _packages[ packageIndex ].GetLocalThumbnailStream(); } public void UpdateAssetInformationThumbnail(IResource defaultThumbnail, Stream fileContent, int packageIndex) { - _packages[packageIndex].EmbeddAssetInformationThumbnail(defaultThumbnail, fileContent); + _packages[ packageIndex ].EmbeddAssetInformationThumbnail(defaultThumbnail, fileContent); Program.signalNewData(0); } + #endregion #region Submodel @@ -207,11 +210,12 @@ public void DeleteSubmodelById(string submodelIdentifier) var submodel = GetSubmodelById(submodelIdentifier, out int packageIndex); if (submodel != null && packageIndex != -1) { - foreach (var aas in _packages[packageIndex].AasEnv.AssetAdministrationShells) + foreach (var aas in _packages[ packageIndex ].AasEnv.AssetAdministrationShells) { _aasService.Value.DeleteSubmodelReferenceById(aas.Id, submodelIdentifier); } - _packages[packageIndex].AasEnv.Submodels.Remove(submodel); + + _packages[ packageIndex ].AasEnv.Submodels.Remove(submodel); _logger.LogDebug($"Deleted submodel with id {submodelIdentifier}."); AasxServer.Program.signalNewData(1); } @@ -236,7 +240,7 @@ public void DeleteSupplementaryFileInPackage(string submodelIdentifier, string f _ = GetSubmodelById(submodelIdentifier, out int packageIndex); if (packageIndex != -1) { - _packages[packageIndex].DeleteSupplementaryFile(filePath); + _packages[ packageIndex ].DeleteSupplementaryFile(filePath); } } @@ -293,7 +297,7 @@ public void DeleteConceptDescriptionById(string cdIdentifier) if ((conceptDescription != null) && (packageIndex != -1)) { - _packages[packageIndex].AasEnv.ConceptDescriptions.Remove(conceptDescription); + _packages[ packageIndex ].AasEnv.ConceptDescriptions.Remove(conceptDescription); _logger.LogDebug($"Delete ConceptDescription with id {cdIdentifier}"); AasxServer.Program.signalNewData(1); } @@ -367,13 +371,12 @@ public IConceptDescription CreateConceptDescription(IConceptDescription body) { if (EmptyPackageAvailable(out int emptyPackageIndex)) { - - _packages[emptyPackageIndex].AasEnv.ConceptDescriptions.Add(body); - var timeStamp = DateTime.UtcNow; + _packages[ emptyPackageIndex ].AasEnv.ConceptDescriptions.Add(body); + var timeStamp = DateTime.UtcNow; body.TimeStampCreate = timeStamp; body.SetTimeStamp(timeStamp); Program.signalNewData(2); - return _packages[emptyPackageIndex].AasEnv.ConceptDescriptions[0]; //Considering it is the first AAS being added to empty package. + return _packages[ emptyPackageIndex ].AasEnv.ConceptDescriptions[ 0 ]; //Considering it is the first AAS being added to empty package. } else { @@ -386,9 +389,9 @@ public void UpdateConceptDescriptionById(IConceptDescription body, string cdIden var conceptDescription = GetConceptDescriptionById(cdIdentifier, out int packageIndex); if (conceptDescription != null && packageIndex != -1) { - var cdIndex = _packages[packageIndex].AasEnv.ConceptDescriptions.IndexOf(conceptDescription); - _packages[packageIndex].AasEnv.ConceptDescriptions.Remove(conceptDescription); - _packages[packageIndex].AasEnv.ConceptDescriptions.Insert(cdIndex, body); + var cdIndex = _packages[ packageIndex ].AasEnv.ConceptDescriptions.IndexOf(conceptDescription); + _packages[ packageIndex ].AasEnv.ConceptDescriptions.Remove(conceptDescription); + _packages[ packageIndex ].AasEnv.ConceptDescriptions.Insert(cdIndex, body); var timeStamp = DateTime.UtcNow; body.TimeStampCreate = timeStamp; body.SetTimeStamp(timeStamp); @@ -403,7 +406,7 @@ public Stream GetFileFromPackage(string submodelIdentifier, string fileName) if (!string.IsNullOrEmpty(fileName)) { var _ = GetSubmodelById(submodelIdentifier, out int packageIndex); - return _packages[packageIndex].GetLocalStreamFromPackage(fileName); + return _packages[ packageIndex ].GetLocalStreamFromPackage(fileName); } else { @@ -417,9 +420,9 @@ public void ReplaceAssetAdministrationShellById(string aasIdentifier, IAssetAdmi var aas = GetAssetAdministrationShellById(aasIdentifier, out int packageIndex); if (aas != null && packageIndex != -1) { - var existingIndex = _packages[packageIndex].AasEnv.AssetAdministrationShells.IndexOf(aas); - _packages[packageIndex].AasEnv.AssetAdministrationShells.Remove(aas); - _packages[packageIndex].AasEnv.AssetAdministrationShells.Insert(existingIndex, newAas); + var existingIndex = _packages[ packageIndex ].AasEnv.AssetAdministrationShells.IndexOf(aas); + _packages[ packageIndex ].AasEnv.AssetAdministrationShells.Remove(aas); + _packages[ packageIndex ].AasEnv.AssetAdministrationShells.Insert(existingIndex, newAas); var timeStamp = DateTime.UtcNow; newAas.TimeStampCreate = timeStamp; newAas.SetTimeStamp(timeStamp); @@ -432,9 +435,9 @@ public void ReplaceSubmodelById(string submodelIdentifier, ISubmodel newSubmodel var submodel = GetSubmodelById(submodelIdentifier, out int packageIndex); if (submodel != null && packageIndex != -1) { - var existingIndex = _packages[packageIndex].AasEnv.Submodels.IndexOf(submodel); - _packages[packageIndex].AasEnv.Submodels.Remove(submodel); - _packages[packageIndex].AasEnv.Submodels.Insert(existingIndex, newSubmodel); + var existingIndex = _packages[ packageIndex ].AasEnv.Submodels.IndexOf(submodel); + _packages[ packageIndex ].AasEnv.Submodels.Remove(submodel); + _packages[ packageIndex ].AasEnv.Submodels.Insert(existingIndex, newSubmodel); var timeStamp = DateTime.UtcNow; newSubmodel.TimeStampCreate = timeStamp; newSubmodel.SetParentAndTimestamp(timeStamp); @@ -492,7 +495,6 @@ public List GetAllSubmodels(IReference reqSemanticId = null, string i output = submodels; } - } } @@ -517,7 +519,7 @@ public ISubmodel CreateSubmodel(ISubmodel newSubmodel, string aasIdentifier = nu newSubmodel.SetAllParents(DateTime.UtcNow); aas.Submodels ??= new List(); aas.Submodels.Add(newSubmodel.GetReference()); - _packages[packageIndex].AasEnv.Submodels.Add(newSubmodel); + _packages[ packageIndex ].AasEnv.Submodels.Add(newSubmodel); var timeStamp = DateTime.UtcNow; aas.SetTimeStamp(timeStamp); newSubmodel.TimeStampCreate = timeStamp; @@ -529,12 +531,12 @@ public ISubmodel CreateSubmodel(ISubmodel newSubmodel, string aasIdentifier = nu if (EmptyPackageAvailable(out int emptyPackageIndex)) { - _packages[emptyPackageIndex].AasEnv.Submodels.Add(newSubmodel); + _packages[ emptyPackageIndex ].AasEnv.Submodels.Add(newSubmodel); var timeStamp = DateTime.UtcNow; newSubmodel.TimeStampCreate = timeStamp; newSubmodel.SetTimeStamp(timeStamp); Program.signalNewData(2); - return _packages[emptyPackageIndex].AasEnv.Submodels[0]; //Considering it is the first AAS being added to empty package. + return _packages[ emptyPackageIndex ].AasEnv.Submodels[ 0 ]; //Considering it is the first AAS being added to empty package. } else { @@ -545,9 +547,9 @@ public ISubmodel CreateSubmodel(ISubmodel newSubmodel, string aasIdentifier = nu public Task ReplaceSupplementaryFileInPackage(string submodelIdentifier, string sourceFile, string targetFile, string contentType, MemoryStream fileContent) { var submodel = GetSubmodelById(submodelIdentifier, out int packageIndex); - return _packages[packageIndex].ReplaceSupplementaryFileInPackageAsync(sourceFile, targetFile, contentType, fileContent); + return _packages[ packageIndex ].ReplaceSupplementaryFileInPackageAsync(sourceFile, targetFile, contentType, fileContent); } #endregion } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/Services/IdShortPathParserService.cs b/src/AasxServerStandardBib/Services/IdShortPathParserService.cs index bede03cd8..706dc8e13 100644 --- a/src/AasxServerStandardBib/Services/IdShortPathParserService.cs +++ b/src/AasxServerStandardBib/Services/IdShortPathParserService.cs @@ -3,17 +3,14 @@ using AasxServerStandardBib.Logging; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace AasxServerStandardBib.Services { - public class IdShortPathParserService :IIdShortPathParserService + public class IdShortPathParserService : IIdShortPathParserService { private IAppLogger _logger; - public IdShortPathParserService(IAppLogger logger) + public IdShortPathParserService(IAppLogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -126,4 +123,4 @@ private static void CheckIfOpeningBracketMissing(int startIndex, string idShort) } } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/Services/MetamodelVerificationService.cs b/src/AasxServerStandardBib/Services/MetamodelVerificationService.cs index 2ed09fc71..5bbde6d88 100644 --- a/src/AasxServerStandardBib/Services/MetamodelVerificationService.cs +++ b/src/AasxServerStandardBib/Services/MetamodelVerificationService.cs @@ -1,5 +1,4 @@ - -using AasxServerStandardBib.Interfaces; +using AasxServerStandardBib.Interfaces; using AasxServerStandardBib.Logging; using AdminShellNS.Exceptions; using Microsoft.Extensions.Configuration; @@ -18,22 +17,16 @@ public MetamodelVerificationService(IAppLogger log _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _configuration = configuration; } + public void VerifyRequestBody(IClass body) { - if (_configuration.GetValue("IsMetamodelVerificationStrict")) + var errorList = Verification.Verify(body).ToList(); + if (errorList.Any()) { - var errorList = Verification.Verify(body).ToList(); - if (errorList.Any()) - { - throw new MetamodelVerificationException(errorList); - } - - _logger.LogDebug($"The request body is conformant with the metamodel."); - } - else - { - _logger.LogDebug("Metamodel verification is not strict. Therefore, skipping the verification."); + throw new MetamodelVerificationException(errorList); } + + _logger.LogDebug($"The request body is conformant with the metamodel."); } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/Services/SubmodelService.cs b/src/AasxServerStandardBib/Services/SubmodelService.cs index 0cabee998..ad05ac594 100644 --- a/src/AasxServerStandardBib/Services/SubmodelService.cs +++ b/src/AasxServerStandardBib/Services/SubmodelService.cs @@ -1,5 +1,4 @@ - -using AasxServer; +using AasxServer; using AasxServerStandardBib.Exceptions; using AasxServerStandardBib.Interfaces; using AasxServerStandardBib.Logging; @@ -8,7 +7,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Reflection.Metadata; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -22,7 +20,8 @@ public class SubmodelService : ISubmodelService private readonly IIdShortPathParserService _pathParserService; private const string SML_IdShortPath_Regex = @"\[(?[\d]+)\]"; - public SubmodelService(IAppLogger logger, IAdminShellPackageEnvironmentService packageEnvService, IMetamodelVerificationService verificationService, IIdShortPathParserService pathParserService) + public SubmodelService(IAppLogger logger, IAdminShellPackageEnvironmentService packageEnvService, IMetamodelVerificationService verificationService, + IIdShortPathParserService pathParserService) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _packageEnvService = packageEnvService ?? throw new ArgumentNullException(nameof(_packageEnvService)); @@ -48,7 +47,6 @@ private bool IsSubmodelElementPresent(string submodelIdentifier, string idShortP _logger.LogInformation($"Found SubmodelElement at {idShortPath} in submodel with Id {submodelIdentifier}"); return true; } - } return false; @@ -63,8 +61,9 @@ private ISubmodelElement GetSubmodelElementByPath(IReferable parent, string idSh if (idShorts.Count == 1) { - return parent.FindSubmodelElementByIdShort((string)idShorts[0]); + return parent.FindSubmodelElementByIdShort((string) idShorts[ 0 ]); } + foreach (var idShortObject in idShorts) { if (output != null) @@ -75,7 +74,7 @@ private ISubmodelElement GetSubmodelElementByPath(IReferable parent, string idSh if (idShortObject is string idShortStr) { output = outParent.FindSubmodelElementByIdShort(idShortStr); - if(output == null) + if (output == null) { return null; } @@ -86,7 +85,7 @@ private ISubmodelElement GetSubmodelElementByPath(IReferable parent, string idSh { try { - output = smeList.Value?[idShortInt]; + output = smeList.Value?[ idShortInt ]; } catch (ArgumentOutOfRangeException ex) { @@ -169,11 +168,11 @@ private ISubmodelElement CreateSubmodelElementByPath(IReferable smeParent, ISubm annotatedRelationshipElement.Annotations ??= new List(); if (first) { - annotatedRelationshipElement.Annotations.Insert(0, (IDataElement)newSubmodelElement); + annotatedRelationshipElement.Annotations.Insert(0, (IDataElement) newSubmodelElement); } else { - annotatedRelationshipElement.Annotations.Add((IDataElement)newSubmodelElement); + annotatedRelationshipElement.Annotations.Add((IDataElement) newSubmodelElement); } } else @@ -215,7 +214,7 @@ public void DeleteSubmodelElementByPath(string submodelIdentifier, string idShor } else if (smeParent is AnnotatedRelationshipElement annotatedRelationshipElement) { - annotatedRelationshipElement.Annotations.Remove((IDataElement)submodelElement); + annotatedRelationshipElement.Annotations.Remove((IDataElement) submodelElement); } else if (smeParent is Entity entity) { @@ -306,7 +305,6 @@ public string GetFileByPath(string submodelIdentifier, string idShortPath, out b if (fileElement != null) { - if (fileElement is AasCore.Aas3_0.File file) { fileName = file.Value; @@ -337,7 +335,6 @@ public string GetFileByPath(string submodelIdentifier, string idShortPath, out b _logger.LogError($"Incorrect value {file.Value} of the Submodel-Element File with IdShort {file.IdShort}"); throw new UnprocessableEntityException($"Incorrect value {file.Value} of the File with IdShort {file.IdShort}."); } - } else { @@ -415,10 +412,8 @@ public ISubmodelElement CreateSubmodelElementByPath(string submodelIdentifier, s { return CreateSubmodelElementByPath(smeParent, newSubmodelElement, first); } - } - public void ReplaceSubmodelById(string submodelIdentifier, ISubmodel newSubmodel) { @@ -460,9 +455,9 @@ public void ReplaceSubmodelElementByPath(string submodelIdentifier, string idSho } else if (smeParent is AnnotatedRelationshipElement annotatedRelElement) { - var existingIndex = annotatedRelElement.Annotations.IndexOf((IDataElement)existingSme); - annotatedRelElement.Annotations.Remove((IDataElement)existingSme); - annotatedRelElement.Annotations.Insert(existingIndex, (IDataElement)newSme); + var existingIndex = annotatedRelElement.Annotations.IndexOf((IDataElement) existingSme); + annotatedRelElement.Annotations.Remove((IDataElement) existingSme); + annotatedRelElement.Annotations.Insert(existingIndex, (IDataElement) newSme); } else { @@ -590,14 +585,12 @@ public void ReplaceFileByPath(string submodelIdentifier, string idShortPath, str file.Value = FormatFileName(targetFile); AasxServer.Program.signalNewData(2); } - } else { throw new NotFoundException($"Submodel element {fileElement.IdShort} is not of type File."); } } - } private string FormatFileName(string fileName) @@ -609,4 +602,4 @@ private string FormatFileName(string fileName) return output; } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/TimeSeries.cs b/src/AasxServerStandardBib/TimeSeries.cs index 32a2d2662..1e0c4d73e 100644 --- a/src/AasxServerStandardBib/TimeSeries.cs +++ b/src/AasxServerStandardBib/TimeSeries.cs @@ -3,11 +3,10 @@ using Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Opc.Ua; using Org.Webpki.JsonCanonicalizer; -using SampleClient; using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -449,65 +448,7 @@ public static void SetOPCClientThread(double value) opcClientRate = (long)value; } - private static void OnOPCClientNextTimedEvent(long ms) - { - if (opcClientRate != 0) - { - opcClientCount += ms; - if (opcClientCount >= opcClientRate) - { - AasxServer.Program.OnOPCClientNextTimedEvent(); - opcClientCount = 0; - } - } - } - - /* - static ulong ChangeNumber = 0; - - static bool setChangeNumber(IReferable r, ulong changeNumber) - { - do - { - r.ChangeNumber = changeNumber; - if (r != r.parent) - { - r = r.parent; - } - else - r = null; - } - while (r != null); - - return true; - } - */ - - /* - private static T AddToSMC( - DateTime timestamp, - SubmodelElementCollection smc, - string idShort, - string semanticIdKey, - string smeValue = null) where T : ISubmodelElement - { - var newElem = CreateSubmodelElementInstance(typeof(T)); - newElem.IdShort = idShort; - newElem.SemanticId = new Reference(AasCore.Aas3_0_RC02.ReferenceTypes.GlobalReference, new List() { new Key(KeyTypes.GlobalReference, semanticIdKey) }); - newElem.SetTimeStamp(timestamp); - newElem.TimeStampCreate = timestamp; - if (smc?.Value != null) - smc.Value.Add(newElem); - if (smeValue != null && newElem is Property newP) - newP.Value = smeValue; - if (smeValue != null && newElem is Blob newB) - newB.Value = Encoding.ASCII.GetBytes(smeValue); - newElem.Qualifiers = new List(); - newElem.DataSpecifications = new List(); - return (T)newElem; - } - */ - + private static ISubmodelElement CreateSubmodelElementInstance(Type type) { if (type == null /*|| !type.IsSubclassOf(typeof(ISubmodelElement))*/) @@ -655,11 +596,7 @@ public static bool timeSeriesSampling(bool final) { if (Program.isLoading) return true; - - OnOPCClientNextTimedEvent(100); - - // ulong newChangeNumber = ChangeNumber + 1; - // bool useNewChangeNumber = false; + DateTime timeStamp = DateTime.UtcNow; foreach (var tsb in timeSeriesBlockList) @@ -731,15 +668,11 @@ public static bool timeSeriesSampling(bool final) } if (tsb.sourceType == "opchd" && tsb.sourceAddress != "") { - GetHistory(tsb); + valueCount = 0; if (table != null) valueCount = table.Count; } - if (tsb.sourceType == "opcda" && tsb.sourceAddress != "") - { - valueCount = GetDAData(tsb); - } if (tsb.sourceType == "modbus" && tsb.sourceAddress != "") { valueCount = GetModbus(tsb); @@ -868,28 +801,7 @@ public static bool timeSeriesSampling(bool final) tsb.samplesValues[i] += latestDataValue; } } - if (tsb.sourceType == "opcda") - { - latestDataValue = opcDAValues[i]; - switch (latestDataValue.ToLower()) - { - case "true": - latestDataValue = "1"; - break; - case "false": - latestDataValue = "0"; - break; - } - if (tsb.destFormat == TimeSeriesDestFormat.TimeSeries10) - { - tsb.samplesValues[i] += $"[{tsb.totalSamples.Value}, {latestDataValue}]"; - } - else - { - tsb.samplesValues[i] += latestDataValue; - } - Console.WriteLine(tsb.opcNodes[i] + " " + opcDAValues[i]); - } + if (tsb.sourceType == "modbus") { latestDataValue = modbusValues[i]; @@ -1331,11 +1243,8 @@ static bool parseJSON(string url, string username, string password, SubmodelElem static List> table = null; static string ErrorMessage { get; set; } - static UASampleClient opc = null; - static Opc.Ua.Client.Session session = null; static DateTime startTime; static DateTime endTime; - static List opcDAValues = null; static List modbusValues = null; static List lastModbusValues = null; static Modbus.ModbusTCPClient mbClient = null; @@ -1419,186 +1328,5 @@ public static int GetModbus(TimeSeriesBlock tsb) return 1; } - public static int GetDAData(TimeSeriesBlock tsb) - { - Console.WriteLine("Read OPC DA Data:"); - try - { - ErrorMessage = ""; - if (session == null) - Connect(tsb); - if (session != null) - { - opcDAValues = new List(); - for (int i = 0; i < tsb.opcNodes.Count; i++) - { - string[] split = tsb.opcNodes[i].Split(','); - string value = opc.ReadSubmodelElementValue(split[1], (ushort)Convert.ToInt32(split[0])); - opcDAValues.Add(value); - } - } - } - catch (Exception ex) - { - ErrorMessage = ex.Message; - return 0; - } - /* - session?.Close(); - session?.Dispose(); - session = null; - */ - - return 1; - } - - public static void GetHistory(TimeSeriesBlock tsb) - { - Console.WriteLine("Read OPC UA Historical Data:"); - try - { - ErrorMessage = ""; - if (session == null) - Connect(tsb); - startTime = tsb.opcLastTimeStamp; - // get current time on server - if (session != null) - endTime = (DateTime)session.ReadValue(new NodeId(2258, 0)).Value; - GetData(tsb); - } - catch (Exception ex) - { - ErrorMessage = ex.Message; - Console.WriteLine(ErrorMessage); - session?.Close(); - session?.Dispose(); - session = null; - opc = null; - } - /* - session?.Close(); - session?.Dispose(); - session = null; - */ - } - public static void Connect(TimeSeriesBlock tsb) - { - Console.WriteLine("Connect OPC UA"); - if (opc == null) - opc = new UASampleClient(tsb.sourceAddress, true, 10000, tsb.username, tsb.password); - opc.ConsoleSampleClient().Wait(); - session = opc.session; - if (session == null) - { - Console.WriteLine("ERROR: Session not connected " - + tsb.sourceAddress + " " + tsb.username + " " + tsb.password); - } - else - { - // get current time on server - tsb.opcLastTimeStamp = (DateTime)session.ReadValue(new NodeId(2258, 0)).Value; - tsb.opcLastTimeStamp -= TimeSpan.FromMinutes(1); - } - } - public static void GetData(TimeSeriesBlock tsb) - { - if (session != null) - { - ReadRawModifiedDetails details = new ReadRawModifiedDetails(); - details.StartTime = startTime; - details.EndTime = endTime; - details.NumValuesPerNode = 0; - details.IsReadModified = false; - details.ReturnBounds = true; - - var nodesToRead = new HistoryReadValueIdCollection(); - for (int i = 0; i < tsb.opcNodes.Count; i++) - { - var nodeToRead = new HistoryReadValueId(); - string[] split = tsb.opcNodes[i].Split(','); - nodeToRead.NodeId = new NodeId(split[1], (ushort)Convert.ToInt32(split[0])); - nodesToRead.Add(nodeToRead); - } - - table = new List>(); - - HistoryReadResultCollection results = null; - DiagnosticInfoCollection diagnosticInfos = null; - - bool loop = true; - while (loop) - { - session.HistoryRead( - null, - new ExtensionObject(details), - TimestampsToReturn.Both, - false, - nodesToRead, - out results, - out diagnosticInfos); - - ClientBase.ValidateResponse(results, nodesToRead); - ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); - - foreach (var res in results) - { - if (StatusCode.IsBad(res.StatusCode)) - { - throw new ServiceResultException(res.StatusCode); - } - } - - if (results.Count > 0) - { - HistoryData[] historyDatas = new HistoryData[results.Count]; - for (int i = 0; i < results.Count; i++) - { - historyDatas[i] = ExtensionObject.ToEncodeable(results[i].HistoryData) as HistoryData; - } - - int dataValuesCount = historyDatas[0].DataValues.Count; - for (int i = 0; i < dataValuesCount; i++) - { - var sourceTimeStamp = historyDatas[0].DataValues[i].SourceTimestamp; - if (sourceTimeStamp != null && sourceTimeStamp >= startTime) - { - bool isValid = true; - var row = new List(); - row.Add(sourceTimeStamp); - - foreach (HistoryData historyData in historyDatas) - { - var value = historyData.DataValues[i].Value?.ToString(); - if (!string.IsNullOrEmpty(value)) - { - row.Add(historyData.DataValues[i].Value); - } - else - { - isValid = false; - break; - } - } - if (isValid) - { - table.Add(row); - tsb.opcLastTimeStamp = sourceTimeStamp + TimeSpan.FromMilliseconds(1); - } - } - } - } - - for (int i = 0; i < results.Count; i++) - { - if (results[i].ContinuationPoint == null || results[i].ContinuationPoint.Length == 0) - { - loop = false; - break; - } - nodesToRead[i].ContinuationPoint = results[i].ContinuationPoint; - } - } - } - } } } diff --git a/src/AasxServerStandardBib/UASampleClient.cs b/src/AasxServerStandardBib/UASampleClient.cs deleted file mode 100644 index 1eeeb7496..000000000 --- a/src/AasxServerStandardBib/UASampleClient.cs +++ /dev/null @@ -1,230 +0,0 @@ -/* Copyright (c) 1996-2016, OPC Foundation. All rights reserved. - The source code in this file is covered under a dual-license scenario: - - RCL: for OPC Foundation members in good-standing - - GPL V2: everybody else - RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/ - GNU General Public License as published by the Free Software Foundation; - version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2 - This source code is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -*/ -using System; -using System.Globalization; -using System.Threading; -using System.Threading.Tasks; -using AdminShellNS; -using Opc.Ua; -using Opc.Ua.Client; -using Opc.Ua.Configuration; - -namespace SampleClient -{ - public class UASampleClient - { - const int ReconnectPeriod = 10; - public Session session; - SessionReconnectHandler reconnectHandler; - string endpointURL; - int clientRunTime = Timeout.Infinite; - static bool autoAccept = true; - static ExitCode exitCode; - string userName; - string password; - - public UASampleClient(string _endpointURL, bool _autoAccept, int _stopTimeout, string _userName, string _password) - { - endpointURL = _endpointURL; - autoAccept = _autoAccept; - clientRunTime = _stopTimeout <= 0 ? Timeout.Infinite : _stopTimeout * 1000; - userName = _userName; - password = _password; - } - - public void Run() - { - try - { - ConsoleSampleClient().Wait(); - } - catch (Exception ex) - { - Utils.Trace("ServiceResultException:" + ex.Message); - Console.WriteLine("Exception: {0}", ex.Message); - Console.WriteLine("press any key to continue"); - return; - } - - ManualResetEvent quitEvent = new ManualResetEvent(false); - try - { - Console.CancelKeyPress += (sender, eArgs) => - { - quitEvent.Set(); - eArgs.Cancel = true; - }; - } - catch - { - } - - // wait for timeout or Ctrl-C - quitEvent.WaitOne(clientRunTime); - - // return error conditions - if (session.KeepAliveStopped) - { - exitCode = ExitCode.ErrorNoKeepAlive; - return; - } - - exitCode = ExitCode.Ok; - } - - public static ExitCode ExitCode { get => exitCode; } - - public async Task ConsoleSampleClient() - { - exitCode = ExitCode.ErrorCreateApplication; - - ApplicationInstance application = new ApplicationInstance - { - ApplicationName = "UA Core Sample Client", - ApplicationType = ApplicationType.Client, - ConfigSectionName = Utils.IsRunningOnMono() ? "Opc.Ua.MonoSampleClient" : "Opc.Ua.SampleClient" - }; - - // load the application configuration. - ApplicationConfiguration config = await application.LoadApplicationConfiguration(false); - - // check the application certificate. - bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0); - if (!haveAppCertificate) - { - throw new Exception("Application instance certificate invalid!"); - } - - if (haveAppCertificate) - { - config.ApplicationUri = X509Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate); - if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) - { - autoAccept = true; - } - config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); - } - else - { - } - - exitCode = ExitCode.ErrorDiscoverEndpoints; - var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate, 15000); - // Console.WriteLine(" Selected endpoint uses: {0}", - selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1); - - exitCode = ExitCode.ErrorCreateSession; - var endpointConfiguration = EndpointConfiguration.Create(config); - var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration); - - if ((userName == "" || userName == null) && (password == "" || password == null)) - { - session = await Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null); - } - else - { - session = await Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(userName, password), null); - } - - // register keep alive handler - session.KeepAlive += Client_KeepAlive; - } - - private void Client_KeepAlive(ISession sender, KeepAliveEventArgs e) - { - if (e.Status != null && ServiceResult.IsNotGood(e.Status)) - { - Console.WriteLine("{0} {1}/{2}", e.Status, sender.OutstandingRequestCount, sender.DefunctRequestCount); - - if (reconnectHandler == null) - { - Console.WriteLine("--- RECONNECTING ---"); - reconnectHandler = new SessionReconnectHandler(); - reconnectHandler.BeginReconnect(sender, ReconnectPeriod * 1000, Client_ReconnectComplete); - } - } - } - - private void Client_ReconnectComplete(object sender, EventArgs e) - { - // ignore callbacks from discarded objects. - if (!Object.ReferenceEquals(sender, reconnectHandler)) - { - return; - } - - session = (Session)reconnectHandler.Session; - reconnectHandler.Dispose(); - reconnectHandler = null; - - Console.WriteLine("--- RECONNECTED ---"); - } - - private static void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e) - { - foreach (var value in item.DequeueValues()) - { - Console.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode); - } - } - - private static void CertificateValidator_CertificateValidation(CertificateValidator validator, CertificateValidationEventArgs e) - { - if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted) - { - e.Accept = autoAccept; - } - } - - public string ReadSubmodelElementValue(string nodeName, int index) - { - NodeId node = new NodeId(nodeName, (ushort)index); - return (session.ReadValue(node).ToString()); - } - - public string ReadSubmodelElementValue(NodeId nodeId) - { - return (session.ReadValue(nodeId).ToString(null, CultureInfo.InvariantCulture)); - } - - public void WriteSubmodelElementValue(NodeId nodeId, object value) - { - WriteValue nodeToWrite = new WriteValue(); - nodeToWrite.NodeId = nodeId; - nodeToWrite.AttributeId = Attributes.Value; - nodeToWrite.Value = new DataValue(); - nodeToWrite.Value.WrappedValue = new Variant(value); - - WriteValueCollection nodesToWrite = new WriteValueCollection(); - nodesToWrite.Add(nodeToWrite); - - // read the attributes. - StatusCodeCollection results = null; - DiagnosticInfoCollection diagnosticInfos = null; - - ResponseHeader responseHeader = session.Write( - null, - nodesToWrite, - out results, - out diagnosticInfos); - - ClientBase.ValidateResponse(results, nodesToWrite); - ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); - - // check for error. - if (StatusCode.IsBad(results[0])) - { - throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); - } - } - } -} diff --git a/src/AasxServerStandardBib/entityFW.cs b/src/AasxServerStandardBib/entityFW.cs index edab3ee6a..15f0aaf5b 100644 --- a/src/AasxServerStandardBib/entityFW.cs +++ b/src/AasxServerStandardBib/entityFW.cs @@ -3,19 +3,11 @@ using Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Primitives; using Microsoft.IdentityModel.Tokens; -using SpookilySharp; using System; -using System.Collections; using System.Collections.Generic; -using System.ComponentModel; -// using System.Drawing; using System.Globalization; -using System.IO; using System.Linq; -using System.Text.RegularExpressions; using static AasCore.Aas3_0.Visitation; // https://learn.microsoft.com/en-us/ef/core/get-started/overview/first-app?tabs=netcore-cli @@ -57,7 +49,8 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) { throw new Exception("No Configuration!"); } - connectionString = _con["DatabaseConnection:ConnectionString"]; + + connectionString = _con[ "DatabaseConnection:ConnectionString" ]; if (connectionString != null) { if (connectionString.Contains("$DATAPATH")) @@ -69,15 +62,17 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) string dbUser = System.Environment.GetEnvironmentVariable("DATABASE_PASSWORD"); for (int i = 0; i < Params.Length; i++) { - if (Params[i].Contains("Username") && dbUser != null) + if (Params[ i ].Contains("Username") && dbUser != null) { - Params[i] = "Username=" + dbUser; + Params[ i ] = "Username=" + dbUser; } - if (Params[i].Contains("Password") && dbPassword != null) + + if (Params[ i ].Contains("Password") && dbPassword != null) { - Params[i] = "Password=" + dbPassword; + Params[ i ] = "Password=" + dbPassword; } } + // Console.WriteLine("Use POSTGRES: " + connectionString); Program.isPostgres = true; options.UseNpgsql(connectionString); @@ -161,7 +156,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) } else { - var connectionString = _con["DatabaseConnection:ConnectionString"]; + var connectionString = _con[ "DatabaseConnection:ConnectionString" ]; if (connectionString.Contains("$DATAPATH")) connectionString = connectionString.Replace("$DATAPATH", AasxHttpContextHelper.DataPath); options.UseSqlite(connectionString); @@ -179,13 +174,14 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) } else { - var connectionString = _con["DatabaseConnection:ConnectionString"]; + var connectionString = _con[ "DatabaseConnection:ConnectionString" ]; if (connectionString.Contains("$DATAPATH")) connectionString = connectionString.Replace("$DATAPATH", AasxHttpContextHelper.DataPath); options.UseNpgsql(connectionString); } } } + public class DbConfigSet { public int Id { get; set; } @@ -195,7 +191,7 @@ public class DbConfigSet public long SMECount { get; set; } } - [Index(nameof(AASXNum))] + [ Index(nameof(AASXNum)) ] public class AASXSet { public int Id { get; set; } @@ -203,7 +199,7 @@ public class AASXSet public string AASX { get; set; } } - [Index(nameof(AasNum))] + [ Index(nameof(AasNum)) ] public class AasSet { public int Id { get; set; } @@ -215,7 +211,7 @@ public class AasSet public string AssetKind { get; set; } } - [Index(nameof(SubmodelNum))] + [ Index(nameof(SubmodelNum)) ] public class SubmodelSet { public int Id { get; set; } @@ -227,8 +223,8 @@ public class SubmodelSet public string SemanticId { get; set; } } - [Index(nameof(SubmodelNum))] - [Index(nameof(SMENum))] + [ Index(nameof(SubmodelNum)) ] + [ Index(nameof(SMENum)) ] public class SMESet { public int Id { get; set; } @@ -263,6 +259,7 @@ public string getValue() break; } } + return ""; } @@ -281,6 +278,7 @@ public List getMLPValue() list.Add(MLPValue.Annotation); list.Add(MLPValue.Value); } + return list; } } @@ -307,24 +305,28 @@ public static List getValueList(List smesets) // SValue, IValue, DValue Tabellen zusammenführen var watch2 = System.Diagnostics.Stopwatch.StartNew(); - valueList = db.SValueSets.FromSqlRaw("SELECT * FROM SValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last + " UNION SELECT * FROM IValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last + " UNION SELECT * FROM DValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last) + valueList = db.SValueSets.FromSqlRaw("SELECT * FROM SValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last + + " UNION SELECT * FROM IValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last + + " UNION SELECT * FROM DValueSets WHERE ParentSMENum >= " + first + " AND ParentSMENum <=" + last) .Where(v => smeNums.Contains(v.ParentSMENum)) .OrderBy(v => v.ParentSMENum) .ToList(); watch2.Stop(); Console.WriteLine("It took this time: " + watch2.ElapsedMilliseconds); } + return valueList; } } - [Index(nameof(ParentSMENum))] + [ Index(nameof(ParentSMENum)) ] public class IntValue { public int Id { get; set; } public long ParentSMENum { get; set; } public long Value { get; set; } public string Annotation { get; set; } + public StringValue asStringValue() { return new StringValue @@ -337,7 +339,7 @@ public StringValue asStringValue() } } - [Index(nameof(ParentSMENum))] + [ Index(nameof(ParentSMENum)) ] public class StringValue { public int Id { get; set; } @@ -346,13 +348,14 @@ public class StringValue public string Annotation { get; set; } } - [Index(nameof(ParentSMENum))] + [ Index(nameof(ParentSMENum)) ] public class DoubleValue { public int Id { get; set; } public long ParentSMENum { get; set; } public double Value { get; set; } public string Annotation { get; set; } + public StringValue asStringValue() { return new StringValue @@ -370,6 +373,7 @@ public class SubmodelResult public string submodelId { get; set; } public string url { get; set; } } + public class SmeResult { public string submodelId { get; set; } @@ -377,6 +381,7 @@ public class SmeResult public string value { get; set; } public string url { get; set; } } + public class Query { public List SearchSubmodels(string semanticId) @@ -402,6 +407,7 @@ public List SearchSubmodels(string semanticId) sr.url = Program.externalBlazor + "/submodels/" + sub64; list.Add(sr); } + Console.WriteLine("Collected result in " + watch.ElapsedMilliseconds + "ms"); } @@ -425,6 +431,7 @@ bool isLowerUpper(string valueType, string value, string lower, string upper) if (!legal.Contains(c)) return false; } + var decSep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; // Console.WriteLine("seperator = " + decSep); lower = lower.Replace(".", decSep); @@ -489,7 +496,7 @@ public List SearchSMEs( iEqual = Convert.ToInt64(equal); withI = true; fEqual = Convert.ToDouble(equal); - withF= true; + withF = true; } else if (lower != "" && upper != "") { @@ -501,7 +508,9 @@ public List SearchSMEs( withF = true; } } - catch { } + catch + { + } if (semanticId == "" && equal == "" && lower == "" && upper == "" && contains == "") return result; @@ -519,8 +528,8 @@ public List SearchSMEs( bool withCompare = !withContains && !withEqual && (lower != "" && upper != ""); var list = db.SValueSets.Where(v => - (withContains && v.Value.Contains(contains)) || - (withEqual && v.Value == equal) + (withContains && v.Value.Contains(contains)) || + (withEqual && v.Value == equal) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -538,8 +547,8 @@ public List SearchSMEs( .ToList(); list.AddRange(db.IValueSets.Where(v => - (withEqual && withI && v.Value == iEqual) || - (withCompare && withI && v.Value >= iLower && v.Value <= iUpper) + (withEqual && withI && v.Value == iEqual) || + (withCompare && withI && v.Value >= iLower && v.Value <= iUpper) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -557,8 +566,8 @@ public List SearchSMEs( .ToList()); list.AddRange(db.DValueSets.Where(v => - (withEqual && withF && v.Value == fEqual) || - (withCompare && withF && v.Value >= fLower && v.Value <= fUpper) + (withEqual && withF && v.Value == fEqual) || + (withCompare && withF && v.Value >= fLower && v.Value <= fUpper) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -595,12 +604,14 @@ public List SearchSMEs( path = smeDB.Idshort + "." + path; pnum = smeDB.ParentSMENum; } + r.idShortPath = path; string sub64 = Base64UrlEncoder.Encode(r.submodelId); r.url = Program.externalBlazor + "/submodels/" + sub64 + "/submodel-elements/" + path; result.Add(r); } } + Console.WriteLine("Collected result in " + watch.ElapsedMilliseconds + "ms"); } @@ -615,7 +626,7 @@ public List SearchSMEsResult( string contains = "", string resultSemanticId = "", string resultIdShort = "" - ) + ) { List result = new List(); @@ -640,7 +651,9 @@ public List SearchSMEsResult( withF = true; } } - catch { } + catch + { + } using (AasContext db = new AasContext()) { @@ -654,8 +667,8 @@ public List SearchSMEsResult( bool withEqual = !withContains && (equal != ""); var list = db.SValueSets.Where(v => - (withContains && v.Value.Contains(contains)) || - (withEqual && v.Value == equal) + (withContains && v.Value.Contains(contains)) || + (withEqual && v.Value == equal) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -690,7 +703,7 @@ public List SearchSMEsResult( .ToList(); list.AddRange(db.IValueSets.Where(v => - (withEqual && withI && v.Value == iEqual) + (withEqual && withI && v.Value == iEqual) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -725,7 +738,7 @@ public List SearchSMEsResult( .ToList()); list.AddRange(db.DValueSets.Where(v => - (withEqual && withF && v.Value == fEqual) + (withEqual && withF && v.Value == fEqual) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -775,9 +788,9 @@ public List SearchSMEsResult( watch.Restart(); var smeResult = db.SMESets.Where(s => - hSubmodel.Contains(s.SubmodelNum) && - ((resultSemanticId != "" && s.SemanticId == resultSemanticId) || - (resultIdShort != "" && s.Idshort == resultIdShort)) + hSubmodel.Contains(s.SubmodelNum) && + ((resultSemanticId != "" && s.SemanticId == resultSemanticId) || + (resultIdShort != "" && s.Idshort == resultIdShort)) ) .ToList(); @@ -813,6 +826,7 @@ public List SearchSMEsResult( } } } + r.idShortPath = path; string sub64 = Base64UrlEncoder.Encode(r.submodelId); if (r.url == "") @@ -821,6 +835,7 @@ public List SearchSMEsResult( result.Add(r); } } + Console.WriteLine("Collected result in " + watch.ElapsedMilliseconds + "ms"); } @@ -859,7 +874,9 @@ public int CountSMEs( withF = true; } } - catch { } + catch + { + } if (semanticId == "" && equal == "" && lower == "" && upper == "" && contains == "") return 0; @@ -879,8 +896,8 @@ public int CountSMEs( bool withCompare = !withContains && !withEqual && (lower != "" && upper != ""); c = db.SValueSets.Where(v => - (withContains && v.Value.Contains(contains)) || - (withEqual && v.Value == equal) + (withContains && v.Value.Contains(contains)) || + (withEqual && v.Value == equal) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -898,8 +915,8 @@ public int CountSMEs( .Count(); c += db.IValueSets.Where(v => - (withEqual && withI && v.Value == iEqual) || - (withCompare && withI && v.Value >= iLower && v.Value <= iUpper) + (withEqual && withI && v.Value == iEqual) || + (withCompare && withI && v.Value >= iLower && v.Value <= iUpper) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -916,9 +933,9 @@ public int CountSMEs( .Where(s => semanticId == "" || s.SemanticId == semanticId) .Count(); - c += db.DValueSets.Where(v => - (withEqual && withF && v.Value == fEqual) || - (withCompare && withF && v.Value >= fLower && v.Value <= fUpper) + c += db.DValueSets.Where(v => + (withEqual && withF && v.Value == fEqual) || + (withCompare && withF && v.Value >= fLower && v.Value <= fUpper) ) .Join(db.SMESets, v => v.ParentSMENum, @@ -948,6 +965,7 @@ public class VisitorAASX : VisitorThrough DbConfigSet _dbConfig = null; long _smNum = 0; List _parentNum = null; + public VisitorAASX(AasContext db, DbConfigSet dbConfigSet, long smNum) { _db = db; @@ -964,7 +982,6 @@ public static void LoadAASInDB(AasContext db, IAssetAdministrationShell aas, lon public static void LoadAASInDB(AasContext db, IAssetAdministrationShell aas, long aasxNum, AdminShellPackageEnv asp, DbConfigSet dbConfig) { - long aasNum = ++dbConfig.AasCount; var aasDB = new AasSet { @@ -1086,12 +1103,15 @@ private string getValueAndType(string v, out string sValue, out long iValue, out fValue = Convert.ToDouble(v); return "F"; } - catch { } + catch + { + } } sValue = v; return "S"; } + private void getValue(ISubmodelElement sme, long smeNum, out string vt, out string sValue, out long iValue, out double fValue) { sValue = ""; @@ -1125,16 +1145,18 @@ private void getValue(ISubmodelElement sme, long smeNum, out string vt, out stri { var mlpval = new StringValue() { - Annotation = ls[i].Language, - Value = ls[i].Text, + Annotation = ls[ i ].Language, + Value = ls[ i ].Text, ParentSMENum = smeNum }; _db.Add(mlpval); } + vt = "S"; sValue = v; } } + if (sme is AasCore.Aas3_0.Range r) { v = r.Min; @@ -1148,7 +1170,7 @@ private void getValue(ISubmodelElement sme, long smeNum, out string vt, out stri v += "$$" + v2; vt = "S"; - sValue= v; + sValue = v; /* if (vt == "S" || vt2 == "S") @@ -1160,6 +1182,7 @@ private void getValue(ISubmodelElement sme, long smeNum, out string vt, out stri */ } } + private long collectSMEData(ISubmodelElement sme) { string st = shortType(sme); @@ -1168,7 +1191,7 @@ private long collectSMEData(ISubmodelElement sme) long smeNum = ++_dbConfig.SMECount; long pn = 0; if (_parentNum.Count > 0) - pn = _parentNum[_parentNum.Count - 1]; + pn = _parentNum[ _parentNum.Count - 1 ]; var semanticId = sme.SemanticId.GetAsIdentifier(); if (semanticId == null) semanticId = ""; @@ -1186,9 +1209,10 @@ private long collectSMEData(ISubmodelElement sme) ParentSMENum = smeNum, Value = sValue, Annotation = "" - }; + }; _db.Add(ValueDB); } + if (vt == "I") { var ValueDB = new IntValue @@ -1199,6 +1223,7 @@ private long collectSMEData(ISubmodelElement sme) }; _db.Add(ValueDB); } + if (vt == "F") { var ValueDB = new DoubleValue @@ -1216,38 +1241,47 @@ private long collectSMEData(ISubmodelElement sme) SMEType = st, SemanticId = semanticId, Idshort = sme.IdShort, - ValueType= vt, + ValueType = vt, SubmodelNum = _smNum, ParentSMENum = pn }; _db.Add(smeDB); return smeNum; } + public override void VisitExtension(IExtension that) { } + public override void VisitAdministrativeInformation(IAdministrativeInformation that) { } + public override void VisitQualifier(IQualifier that) { } + public override void VisitAssetAdministrationShell(IAssetAdministrationShell that) { } + public override void VisitAssetInformation(IAssetInformation that) { } + public override void VisitResource(IResource that) { } + public override void VisitSpecificAssetId(ISpecificAssetId that) { } + public override void VisitSubmodel(ISubmodel that) { base.VisitSubmodel(that); } + public override void VisitRelationshipElement(IRelationshipElement that) { long smeNum = collectSMEData(that); @@ -1255,6 +1289,7 @@ public override void VisitRelationshipElement(IRelationshipElement that) base.VisitRelationshipElement(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitSubmodelElementList(ISubmodelElementList that) { long smeNum = collectSMEData(that); @@ -1262,6 +1297,7 @@ public override void VisitSubmodelElementList(ISubmodelElementList that) base.VisitSubmodelElementList(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitSubmodelElementCollection(ISubmodelElementCollection that) { long smeNum = collectSMEData(that); @@ -1269,6 +1305,7 @@ public override void VisitSubmodelElementCollection(ISubmodelElementCollection t base.VisitSubmodelElementCollection(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitProperty(IProperty that) { long smeNum = collectSMEData(that); @@ -1276,6 +1313,7 @@ public override void VisitProperty(IProperty that) base.VisitProperty(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitMultiLanguageProperty(IMultiLanguageProperty that) { long smeNum = collectSMEData(that); @@ -1283,6 +1321,7 @@ public override void VisitMultiLanguageProperty(IMultiLanguageProperty that) base.VisitMultiLanguageProperty(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitRange(AasCore.Aas3_0.IRange that) { long smeNum = collectSMEData(that); @@ -1290,6 +1329,7 @@ public override void VisitRange(AasCore.Aas3_0.IRange that) base.VisitRange(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitReferenceElement(IReferenceElement that) { long smeNum = collectSMEData(that); @@ -1297,6 +1337,7 @@ public override void VisitReferenceElement(IReferenceElement that) base.VisitReferenceElement(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitBlob(IBlob that) { long smeNum = collectSMEData(that); @@ -1304,6 +1345,7 @@ public override void VisitBlob(IBlob that) base.VisitBlob(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitFile(AasCore.Aas3_0.IFile that) { long smeNum = collectSMEData(that); @@ -1311,6 +1353,7 @@ public override void VisitFile(AasCore.Aas3_0.IFile that) base.VisitFile(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitAnnotatedRelationshipElement(IAnnotatedRelationshipElement that) { long smeNum = collectSMEData(that); @@ -1318,6 +1361,7 @@ public override void VisitAnnotatedRelationshipElement(IAnnotatedRelationshipEle base.VisitAnnotatedRelationshipElement(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitEntity(IEntity that) { long smeNum = collectSMEData(that); @@ -1325,12 +1369,15 @@ public override void VisitEntity(IEntity that) base.VisitEntity(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitEventPayload(IEventPayload that) { } + public override void VisitBasicEventElement(IBasicEventElement that) { } + public override void VisitOperation(IOperation that) { long smeNum = collectSMEData(that); @@ -1338,9 +1385,11 @@ public override void VisitOperation(IOperation that) base.VisitOperation(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitOperationVariable(IOperationVariable that) { } + public override void VisitCapability(ICapability that) { long smeNum = collectSMEData(that); @@ -1348,12 +1397,15 @@ public override void VisitCapability(ICapability that) base.VisitCapability(that); _parentNum.RemoveAt(_parentNum.Count - 1); } + public override void VisitConceptDescription(IConceptDescription that) { } + public override void VisitReference(AasCore.Aas3_0.IReference that) { } + public override void VisitKey(IKey that) { } @@ -1365,49 +1417,70 @@ public override void VisitEnvironment(AasCore.Aas3_0.IEnvironment that) public override void VisitLangStringNameType( ILangStringNameType that ) - { } + { + } + public override void VisitLangStringTextType( ILangStringTextType that ) - { } + { + } + public override void VisitEmbeddedDataSpecification( IEmbeddedDataSpecification that ) - { } + { + } + public override void VisitLevelType( ILevelType that ) - { } + { + } + public override void VisitValueReferencePair( IValueReferencePair that ) - { } + { + } + public override void VisitValueList( IValueList that ) - { } + { + } + public override void VisitLangStringPreferredNameTypeIec61360( ILangStringPreferredNameTypeIec61360 that ) - { } + { + } + public override void VisitLangStringShortNameTypeIec61360( ILangStringShortNameTypeIec61360 that ) - { } + { + } + public override void VisitLangStringDefinitionTypeIec61360( ILangStringDefinitionTypeIec61360 that ) - { } + { + } + public override void VisitDataSpecificationIec61360( IDataSpecificationIec61360 that ) - { } - + { + } } public class DBRead { - public DBRead() { } + public DBRead() + { + } + static public Submodel getSubmodel(string submodelId) { using (AasContext db = new AasContext()) @@ -1421,14 +1494,14 @@ static public Submodel getSubmodel(string submodelId) if (subDB != null) { var SMEList = db.SMESets - .OrderBy(sme => sme.SMENum) - .Where(sme => sme.SubmodelNum == subDB.SubmodelNum) - .ToList(); + .OrderBy(sme => sme.SMENum) + .Where(sme => sme.SubmodelNum == subDB.SubmodelNum) + .ToList(); Submodel submodel = new Submodel(submodelId); submodel.IdShort = subDB.Idshort; submodel.SemanticId = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, - new List() { new Key(KeyTypes.GlobalReference, subDB.SemanticId) }); + new List() {new Key(KeyTypes.GlobalReference, subDB.SemanticId)}); loadSME(submodel, null, null, SMEList, 0); @@ -1460,11 +1533,11 @@ static public string getSubmodelJson(string submodelId) static private void loadSME(Submodel submodel, ISubmodelElement sme, string SMEType, List SMEList, long smeNum) { - var smeLevel = SMEList.Where(s => s.ParentSMENum== smeNum).OrderBy(s => s.Idshort).ToList(); + var smeLevel = SMEList.Where(s => s.ParentSMENum == smeNum).OrderBy(s => s.Idshort).ToList(); foreach (var smel in smeLevel) { - ISubmodelElement nextSME= null; + ISubmodelElement nextSME = null; switch (smel.SMEType) { case "P": @@ -1495,13 +1568,14 @@ static private void loadSME(Submodel submodel, ISubmodelElement sme, string SMET nextSME = new AasCore.Aas3_0.File("text", idShort: smel.Idshort, value: smel.getValue()); break; } + if (nextSME == null) continue; if (smel.SemanticId != "") { nextSME.SemanticId = new Reference(AasCore.Aas3_0.ReferenceTypes.ExternalReference, - new List() { new Key(KeyTypes.GlobalReference, smel.SemanticId) }); + new List() {new Key(KeyTypes.GlobalReference, smel.SemanticId)}); } if (sme == null) @@ -1510,7 +1584,7 @@ static private void loadSME(Submodel submodel, ISubmodelElement sme, string SMET } else { - switch(SMEType) + switch (SMEType) { case "SEC": (sme as SubmodelElementCollection).Value.Add(nextSME); @@ -1552,4 +1626,4 @@ static private void loadSME(Submodel submodel, ISubmodelElement sme, string SMET } } } -} +} \ No newline at end of file diff --git a/src/AasxServerStandardBib/i40Language.cs b/src/AasxServerStandardBib/i40Language.cs deleted file mode 100644 index 270d0aeaf..000000000 --- a/src/AasxServerStandardBib/i40Language.cs +++ /dev/null @@ -1,2161 +0,0 @@ - -using AdminShellNS; -using Extensions; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; - -/* -Copyright (c) 2019-2020 PHOENIX CONTACT GmbH & Co. KG , author: Andreas Orzelski -Copyright (c) 2018-2020 Festo SE & Co. KG , author: Michael Hoffmeister -*/ - -namespace AasxServer -{ - public class i40LanguageAutomaton - { - public SubmodelElementCollection automatonControl; - - public string name = ""; - public string getStatus = "stop"; - public string getActualStates = ""; - public string getTransitionsEnabled = ""; - public string setMode = ""; - public string getErrors = ""; - public List getMessages = new List(); - public string setForcedStates = ""; - public string setSingleStep = ""; - public string setSteppingTime = "3"; - - public string[] frameNames; - public Dictionary[] frameContent; - - public Dictionary constants; - - public Dictionary variablesStrings; - public Dictionary variablesCollections; - - public HashSet states = new HashSet(); - public HashSet initialStates = new HashSet(); - public HashSet actualStates = new HashSet(); - - public List transitions; - - public int tick = 0; - public int maxTick = 2; - - public i40LanguageAutomaton() - { - - } - } - - public static class i40LanguageRuntime - { - public static List automatons = new List { }; - public static Thread i40LanguageThread; - public static ThreadStart threadDelegate; - static public void initialize() - { - int aascount = Program.env.Length; - - for (int envi = 0; envi < aascount; envi++) - { - if (Program.env[envi] != null) - { - foreach (var sm in Program.env[envi].AasEnv.Submodels) - { - if (sm != null && sm.IdShort != null) - { - bool withI40Language = false; - int count = sm.Qualifiers.Count; - if (count != 0) - { - int j = 0; - - while (j < count) // Scan qualifiers - { - var p = sm.Qualifiers[j] as Qualifier; - - if (p.Type == "i40language") - { - withI40Language = true; - } - j++; - } - } - if (withI40Language) - { - var auto = new i40LanguageAutomaton(); - automatons.Add(auto); - auto.name = sm.IdShort; - if (auto.name == "automatonServiceRequester") - isRequester = true; - if (auto.name == "automatonServiceProvider") - isProvider = true; - - foreach (var smw1 in sm.SubmodelElements) - { - var sme1 = smw1; - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "automatonControl") - { - var smc1 = sme1 as SubmodelElementCollection; - auto.automatonControl = smc1; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is Property && sme2.IdShort == "setSteppingTime") - { - string value = (sme2 as Property).Value; - Regex regex = new Regex(@"^\d+$"); - if (regex.IsMatch(value)) - { - auto.setSteppingTime = value; - } - else - { - (sme2 as Property).Value = auto.setSteppingTime; - } - } - } - } - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "frames") - { - var smc1 = sme1 as SubmodelElementCollection; - auto.frameNames = new string[smc1.Value.Count]; - auto.frameContent = new Dictionary[smc1.Value.Count]; - - int i = 0; - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is SubmodelElementCollection) - { - var smc2 = sme2 as SubmodelElementCollection; - auto.frameNames[i] = smc2.IdShort; - auto.frameContent[i] = new Dictionary(); - - foreach (var smw3 in smc2.Value) - { - var sme3 = smw3; - if (sme3 is Property) - { - auto.frameContent[i].Add(sme3.IdShort, (sme3 as Property).Value); - } - } - } - i++; - } - } - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "constants") - { - var smc1 = sme1 as SubmodelElementCollection; - auto.constants = new Dictionary(); - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is Property) - { - auto.constants.Add(sme2.IdShort, (sme2 as Property).Value); - } - } - } - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "variables") - { - var smc1 = sme1 as SubmodelElementCollection; - auto.variablesStrings = new Dictionary(); - auto.variablesCollections = new Dictionary(); - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is Property) - { - auto.variablesStrings.Add(sme2.IdShort, (sme2 as Property).Value); - } - if (sme2 is SubmodelElementCollection) - { - auto.variablesCollections.Add(sme2.IdShort, (sme2 as SubmodelElementCollection)); - } - } - } - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "states") - { - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is Property || (sme2 is SubmodelElementCollection && sme2.IdShort != "initialStates")) - { - auto.states.Add(sme2.IdShort); - } - if (sme2 is SubmodelElementCollection && sme2.IdShort == "initialStates") - { - var smc2 = sme2 as SubmodelElementCollection; - - foreach (var smw3 in smc2.Value) - { - var sme3 = smw3; - if (sme3 is Property || (sme3 is SubmodelElementCollection && sme3.IdShort != "initialStates")) - { - auto.initialStates.Add(sme3.IdShort); - auto.states.Add(sme3.IdShort); - } - } - } - } - } - - if (sme1 is SubmodelElementCollection && sme1.IdShort == "transitions") - { - var smc1 = sme1 as SubmodelElementCollection; - auto.transitions = new List(); - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - if (sme2 is SubmodelElementCollection) - { - auto.transitions.Add(sme2 as SubmodelElementCollection); - } - } - } - } - - auto.actualStates = auto.initialStates; - auto.getStatus = "run"; - auto.maxTick = Convert.ToInt32(auto.setSteppingTime); - } - } - } - } - } - - if (automatons.Count != 0) - { - threadDelegate = new ThreadStart(nextTick); - i40LanguageThread = new Thread(threadDelegate); - // MICHA - // i40LanguageThread.Start(); - } - } - - static bool treeChanged = false; - - // public static string debugAutomaton = ""; - // public static string debugAutomaton = "automatonServiceRequester"; - public static string debugAutomaton = "automatonServiceProvider"; - public static void nextTick() - { - while (true) - { - foreach (var auto in automatons) - { - // if (auto.name != "automatonServiceRequester") - // if (auto.name != "automatonServiceProvider") - // continue; - - if (auto.name == debugAutomaton) - { - } - - // get actual automaton data from AAS - foreach (var smw1 in auto.automatonControl.Value) - { - var sme1 = smw1; - if (sme1 is Property && sme1.IdShort == "setMode") - { - auto.setMode = (sme1 as Property).Value; - } - if (sme1 is Property && sme1.IdShort == "stopAtStates") - { - string stopAtStates = (sme1 as Property).Value; - string[] states = stopAtStates.Split(' '); - foreach (var s in states) - if (auto.actualStates.Contains(s)) - auto.setMode = "stop"; - } - if (sme1 is Property && sme1.IdShort == "setForcedStates") - { - auto.setForcedStates = (sme1 as Property).Value; - (sme1 as Property).Value = ""; - } - if (sme1 is Property && sme1.IdShort == "setSingleStep") - { - auto.setSingleStep = (sme1 as Property).Value; - (sme1 as Property).Value = ""; - } - if (sme1 is Property && sme1.IdShort == "setSteppingTime") - { - string value = (sme1 as Property).Value; - Regex regex = new Regex(@"^\d+$"); - if (regex.IsMatch(value)) - { - auto.setSteppingTime = value; - auto.maxTick = Convert.ToInt32(auto.setSteppingTime); - } - } - } - - if (auto.setMode == "stop") - continue; - - if (auto.setMode == "step" && auto.setSingleStep != "step") - continue; - - if (auto.setMode == "force") - { - if (auto.setForcedStates == "") - continue; - - auto.actualStates.Clear(); - string[] states = auto.setForcedStates.Split(' '); - foreach (var s in states) - auto.actualStates.Add(s); - } - - if (auto.tick >= auto.maxTick) - { - if (auto.name == debugAutomaton) - { - } - - auto.tick = 0; - - // Console.WriteLine(auto.name + ":"); - string states = ""; - foreach (var s in auto.actualStates) - { - states += s + " "; - } - // Console.WriteLine("states = " + states); - - List transitionsEnabled = new List(); - List transitionsActive = new List(); - List fromStates = new List(); - List toStates = new List(); - - // collect enabled transitons - foreach (var t in auto.transitions) - { - foreach (var smw1 in t.Value) - { - var sme1 = smw1; - if (sme1 is SubmodelElementCollection && (sme1.IdShort == "from" || sme1.IdShort == "From")) - { - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - - fromStates.Add(sme2.IdShort); - } - } - } - - bool allFromStatesActive = true; - foreach (var from in fromStates) - { - if (!auto.actualStates.Contains(from)) - { - allFromStatesActive = false; - break; - } - } - if (allFromStatesActive) - { - transitionsEnabled.Add(t.IdShort); - } - fromStates.Clear(); - } - - string enabled = ""; - foreach (var te in transitionsEnabled) - { - enabled += te + " "; - } - // Console.WriteLine("Transition enabled: " + enabled); - - // Check which enabled transitions are active by their inputs - foreach (var t in auto.transitions) - { - if (transitionsEnabled.Contains(t.IdShort)) - { - bool includesInput = false; - foreach (var smw1 in t.Value) - { - var sme1 = smw1; - if (sme1 is SubmodelElementCollection && sme1.IdShort == "input") - { - includesInput = true; - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - - if (sme2 is Operation) - { - if (auto.name == debugAutomaton) - { - } - - var op = sme2 as Operation; - // Console.WriteLine("Operation: " + op.IdShort); - bool opResult = false; - switch (op.IdShort) - { - case "wait": - opResult = operation_wait(op, auto); - if (opResult) - transitionsActive.Add(t.IdShort); - break; - case "message": - opResult = operation_message(op, auto); - break; - case "checkCollection": - opResult = operation_checkCollection(op, auto); - if (opResult) - transitionsActive.Add(t.IdShort); - break; - case "check": - opResult = operation_check(op, auto); - if (opResult) - transitionsActive.Add(t.IdShort); - break; - case "receiveProposals": - opResult = operation_receiveProposals(op, auto); - if (opResult) - transitionsActive.Add(t.IdShort); - break; - case "receiveSRAnswer": - opResult = operation_receiveSRAnswer(op, auto); - break; - case "receiveI40message": - opResult = operation_receiveI40message(op, auto); - break; - case "executeLogic": - opResult = operation_executeLogic(op, auto); - break; - case "sendI40frame": - opResult = operation_sendI40frame(op, auto); - break; - case "receiveI40frame": - opResult = operation_receiveI40frame(op, auto); - break; - case "calculate": - opResult = operation_calculate(op, auto); - break; - default: - transitionsActive.Add(t.IdShort); - break; - } - } - } - } - } - if (!includesInput) - transitionsActive.Add(t.IdShort); - } - } - - // collect fromStates and toStates from enabled transitions - foreach (var t in auto.transitions) - { - if (transitionsActive.Contains(t.IdShort)) - { - // execute output operations - foreach (var smw1 in t.Value) - { - var sme1 = smw1; - if (sme1 is SubmodelElementCollection && sme1.IdShort == "output") - { - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - - if (sme2 is Operation) - { - if (auto.name == debugAutomaton) - { - } - - var op = sme2 as Operation; - // Console.WriteLine("Operation: " + op.IdShort); - bool opResult = false; - switch (op.IdShort) - { - case "message": - opResult = operation_message(op, auto); - break; - case "clearMessages": - opResult = operation_clearMessages(op, auto); - break; - case "clear": - opResult = operation_clear(op, auto); - break; - case "sendFrame": - opResult = operation_sendFrame(op, auto); - break; - case "sendI40message": - opResult = operation_sendI40message(op, auto); - break; - case "processRequesterResponse": - opResult = operation_processRequesterResponse(op, auto); - break; - case "executeLogic": - opResult = operation_executeLogic(op, auto); - break; - case "sendI40frame": - opResult = operation_sendI40frame(op, auto); - break; - case "receiveI40frame": - opResult = operation_receiveI40frame(op, auto); - break; - case "calculate": - opResult = operation_calculate(op, auto); - break; - } - } - } - } - - // changes states - foreach (var smw21 in t.Value) - { - sme1 = smw21; - if (sme1 is SubmodelElementCollection && (sme1.IdShort == "from" || sme1.IdShort == "From")) - { - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - - if (!fromStates.Contains(sme2.IdShort)) - fromStates.Add(sme2.IdShort); - } - } - if (sme1 is SubmodelElementCollection && (sme1.IdShort == "to" || sme1.IdShort == "To")) - { - var smc1 = sme1 as SubmodelElementCollection; - - foreach (var smw2 in smc1.Value) - { - var sme2 = smw2; - - if (!toStates.Contains(sme2.IdShort)) - toStates.Add(sme2.IdShort); - } - } - } - } - } - } - - // remove fromStates from activeStates and add toStates to activeStates - foreach (var from in fromStates) - { - auto.actualStates.Remove(from); - } - foreach (var to in toStates) - { - if (!fromStates.Contains(to)) - if (!auto.actualStates.Contains(to)) - auto.actualStates.Add(to); - } - // self loops are only allowed if no other states are active - - // Console.WriteLine(); - - // display actual automaton data in AAS - foreach (var smw1 in auto.automatonControl.Value) - { - var sme1 = smw1; - if (sme1 is Property && sme1.IdShort == "getActualTime") - { - (sme1 as Property).Value = DateTime.UtcNow.ToString(); - } - if (sme1 is Property && sme1.IdShort == "getStatus") - { - (sme1 as Property).Value = auto.getStatus; - } - if (sme1 is Property && sme1.IdShort == "getActualStates") - { - (sme1 as Property).Value = ""; - foreach (var s in auto.actualStates) - { - (sme1 as Property).Value += s + " "; - } - } - if (sme1 is Property && sme1.IdShort == "getTransitionsEnabled") - { - (sme1 as Property).Value = ""; - foreach (var t in transitionsEnabled) - { - (sme1 as Property).Value += t + " "; - } - } - if (sme1 is Property && sme1.IdShort == "getErrors") - { - (sme1 as Property).Value = auto.getErrors; - } - if (sme1 is Property && sme1.IdShort == "getMessages") - { - string value = ""; - foreach (var text in auto.getMessages) - { - if (value != "") - value += ", "; - value += text; - } - (sme1 as Property).Value = value; - } - /* - if (sme1 is Property && sme1.IdShort == "setMode") - { - (sme1 as Property).Value = ""; - } - if (sme1 is Property && sme1.IdShort == "setForcedStates") - { - (sme1 as Property).Value = ""; - } - if (sme1 is Property && sme1.IdShort == "setSingleStep") - { - (sme1 as Property).Value = ""; - } - if (sme1 is Property && sme1.IdShort == "setSteppingTime") - { - string value = (sme1 as Property).Value; - Regex regex = new Regex(@"^\d+$"); - if (regex.IsMatch(value)) - { - auto.setSteppingTime = value; - auto.maxTick = Convert.ToInt32(auto.setSteppingTime); - } - } - */ - } - } - auto.tick++; - } - - int mode = 0; - if (treeChanged) - mode = 2; - Program.signalNewData(mode); - Thread.Sleep(1000); - } - } - - public static bool operation_message(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property value = text - foreach (var v in op.InputVariables) - { - if (v.Value is Property) - { - var p = v.Value as Property; - if (auto.getMessages.Count < 100) - auto.getMessages.Add(p.Value); - if (auto.getMessages.Count == 100) - auto.getMessages.Add("+++"); - // Console.WriteLine("operation message: " + p.IdShort + " = " + p.Value); - } - } - return true; - } - - public static bool operation_clearMessages(Operation op, i40LanguageAutomaton auto) - { - auto.getMessages.Clear(); - return true; - } - - public static bool operation_wait(Operation op, i40LanguageAutomaton auto) - { - // inputVariable reference waitingTime: property value - // outputVariable reference endTime: property value - - if (op.InputVariables.Count != 1 && op.OutputVariables.Count != 1) - { - return false; - } - - var in1 = op.InputVariables.First(); - var r1 = in1.Value; - if (!(r1 is ReferenceElement)) - return false; - var ref1 = Program.env[0].AasEnv.FindReferableByReference((r1 as ReferenceElement).GetModelReference()); - if (ref1 == null) - auto.getErrors += r1.IdShort + " not found! "; - if (!(ref1 is Property)) - return false; - var p1 = ref1 as Property; - int waitingTime = Convert.ToInt32(p1.Value); - - var out1 = op.OutputVariables.First(); - var r2 = out1.Value; - if (!(r2 is ReferenceElement)) - return false; - var ref2 = Program.env[0].AasEnv.FindReferableByReference((r2 as ReferenceElement).GetModelReference()); - if (ref2 == null) - auto.getErrors += r2.IdShort + " not found! "; - if (!(ref2 is Property)) - return false; - var p2 = ref2 as Property; - - DateTime localTime = DateTime.UtcNow; - if (p2.Value == "") // start - { - var endTime = localTime.AddSeconds(waitingTime); - p2.Value = endTime.ToString(); - // Console.WriteLine("endTime = " + p2.Value); - } - else // test if time has elapsed - { - // Console.WriteLine("localTime = " + localTime); - var endTime = DateTime.Parse(p2.Value); - if (DateTime.Compare(localTime, endTime) > 0) - { - p2.Value = ""; - return true; - } - } - - return false; - } - - public static bool operation_receiveProposals(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: memory, connect - // inputVariable reference frame proposal: collection - // inputVariable reference submodel - // outputVariable reference collected proposals: collection - // outputVariable reference collected not understood proposals: collection - // outputVariable reference collected refused proposals: collection - // outputVariable reference property receivedFrameJSON - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 3 && op.OutputVariables.Count != 4) - { - return false; - } - - Submodel refSubmodel = null; - Property protocol = null; - Property receivedFrameJSON = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property) - { - protocol = (inputRef as Property); - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Submodel) - refSubmodel = refElement as Submodel; - } - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is Property) - receivedFrameJSON = refElement as Property; - } - - var out1 = op.OutputVariables.First(); - var r2 = out1.Value; - if (!(r2 is ReferenceElement)) - return false; - var ref2 = Program.env[0].AasEnv.FindReferableByReference((r2 as ReferenceElement).GetModelReference()); - if (ref2 == null) - auto.getErrors += r2.IdShort + " not found! "; - if (!(ref2 is SubmodelElementCollection)) - return false; - var smc2 = ref2 as SubmodelElementCollection; - - if (protocol.Value != "memory" && protocol.Value != "connect") - return false; - while ((auto.name == "automatonServiceRequester" && receivedFrameJSONRequester.Count != 0) - || (auto.name == "automatonServiceProvider" && receivedFrameJSONProvider.Count != 0)) - { - string receivedFrame = ""; - if (auto.name == "automatonServiceRequester") - { - // receivedFrame = sendFrameJSONProvider; - // sendFrameJSONProvider = ""; - if (receivedFrameJSONRequester.Count != 0) - { - receivedFrame = receivedFrameJSONRequester[0]; - receivedFrameJSONRequester.RemoveAt(0); - } - } - - if (auto.name == "automatonServiceProvider") - { - // receivedFrame = sendFrameJSONRequester; - // sendFrameJSONRequester = ""; - if (receivedFrameJSONProvider.Count != 0) - { - receivedFrame = receivedFrameJSONProvider[0]; - receivedFrameJSONProvider.RemoveAt(0); - } - } - - receivedFrameJSON.Value = receivedFrame; - - ISubmodel submodel = null; - - if (receivedFrame != "") - { - try - { - if (auto.name == debugAutomaton) - { - } - - I40Message_Interaction newBiddingMessage = Newtonsoft.Json.JsonConvert.DeserializeObject( - receivedFrame, new AdminShellConverters.JsonAasxConverter("modelType", "name")); - - submodel = newBiddingMessage.interactionElements[0]; - Console.WriteLine("A new Call for Proposal is received"); - if (submodel != null) - { - if (submodel.IdShort == "Boring") - { - boringSubmodel = submodel; - boringSubmodelFrame = newBiddingMessage.frame; - } - SubmodelElementCollection smcSubmodel = new SubmodelElementCollection(); - smcSubmodel.IdShort = submodel.IdShort; - foreach (var sme in submodel.SubmodelElements) - { - smcSubmodel.Value.Add(sme); - treeChanged = true; - } - smc2.Value.Add(smcSubmodel); - - } - - } - catch - { - } - } - - } - - return true; - } - - public static bool operation_receiveI40message(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: i40connect - // inputVariable property protocolServer: URL - // alternative 1 - // inputVariable reference submodel - // outputVariable reference collected proposals: collection - // alternative 2 - // outputVariable reference messageType - // alternatives end - // outputVariable reference property receivedFrameJSON - - if (auto.name == debugAutomaton) - { - } - - if ((op.InputVariables.Count < 2 && op.InoutputVariables.Count > 3) && op.OutputVariables.Count != 2) - { - return false; - } - - Property protocol = null; - Property protocolServer = null; - SubmodelElementCollection refProposals = null; - Submodel refSubmodel = null; - Property messageType = null; - Property receivedFrameJSON = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property p) - { - if (p.IdShort == "protocol") - protocol = p; - if (p.IdShort == "protocolServer") - protocolServer = p; - } - if (refElement is Submodel s) - { - refSubmodel = s; - } - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection smc) - refProposals = smc; - if (refElement is Property p) - { - if (refProposals == null && messageType == null) - messageType = p; - else - receivedFrameJSON = p; - } - } - - if (protocol.Value != "memory" && protocol.Value != "i40connect") - return false; - - while ((auto.name == "automatonServiceRequester" && receivedFrameJSONRequester.Count != 0) - || (auto.name == "automatonServiceProvider" && receivedFrameJSONProvider.Count != 0)) - { - string receivedFrame = ""; - if (auto.name == "automatonServiceRequester") - { - // receivedFrame = sendFrameJSONProvider; - // sendFrameJSONProvider = ""; - if (receivedFrameJSONRequester.Count != 0) - { - receivedFrame = receivedFrameJSONRequester[0]; - receivedFrameJSONRequester.RemoveAt(0); - } - } - - if (auto.name == "automatonServiceProvider") - { - // receivedFrame = sendFrameJSONRequester; - // sendFrameJSONRequester = ""; - if (receivedFrameJSONProvider.Count != 0) - { - receivedFrame = receivedFrameJSONProvider[0]; - receivedFrameJSONProvider.RemoveAt(0); - } - } - - receivedFrameJSON.Value = receivedFrame; - - ISubmodel submodel = null; - - if (receivedFrame != "") - { - try - { - if (auto.name == debugAutomaton) - { - } - - I40Message_Interaction newBiddingMessage = Newtonsoft.Json.JsonConvert.DeserializeObject( - receivedFrame, new AdminShellConverters.JsonAasxConverter("modelType", "name")); - - if (newBiddingMessage.interactionElements.Count != 0) - { - submodel = newBiddingMessage.interactionElements[0]; - Console.WriteLine("A new Call for Proposal is received"); - if (submodel != null) - { - if (submodel.IdShort == "Boring") - { - boringSubmodel = submodel; - boringSubmodelFrame = newBiddingMessage.frame; - } - SubmodelElementCollection smcSubmodel = new SubmodelElementCollection(); - smcSubmodel.IdShort = submodel.IdShort; - foreach (var sme in submodel.SubmodelElements) - { - smcSubmodel.Value.Add(sme); - treeChanged = true; - } - refProposals.Value.Add(smcSubmodel); - } - } - else - { - if (messageType != null) - messageType.Value = newBiddingMessage.frame.type; - } - } - catch - { - } - } - } - - return true; - } - - public static bool operation_receiveSRAnswer(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: memory, connect - // inputVariable reference frame proposal: collection - // inputVariable reference submodel - // outputVariable reference collected proposals: collection - // outputVariable reference collected not understood proposals: collection - // outputVariable reference collected refused proposals: collection - // outputVariable reference property receivedFrameJSON - - if (auto.name == debugAutomaton) - { - } - - Console.WriteLine("Waiting for Service Requester Answer"); - - while (auto.name == "automatonServiceProvider" && receivedFrameJSONProvider.Count != 0) - { - string receivedFrame = ""; - - if (auto.name == "automatonServiceProvider") - { - // receivedFrame = sendFrameJSONRequester; - // sendFrameJSONRequester = ""; - if (receivedFrameJSONProvider.Count != 0) - { - receivedFrame = receivedFrameJSONProvider[0]; - receivedFrameJSONProvider.RemoveAt(0); - } - } - if (receivedFrame != "") - { - try - { - if (auto.name == debugAutomaton) - { - } - - I40Message_Interaction newBiddingMessage = Newtonsoft.Json.JsonConvert.DeserializeObject( - receivedFrame, new AdminShellConverters.JsonAasxConverter("modelType", "name")); - - srAnswerMessageType = newBiddingMessage.frame.type; - - } - catch - { - } - } - - - } - - return true; - } - - - public static ISubmodel boringSubmodel = null; - public static I40TransmitFrame boringSubmodelFrame = null; - - public static bool isRequester = false; - public static bool isProvider = false; - public static string sendProtocolRequester = ""; - public static string sendProtocolProvider = ""; - public static string receiveProtocolRequester = ""; - public static string receiveProtocolProvider = ""; - public static List sendFrameJSONRequester = new List(); - public static List receivedFrameJSONProvider = new List(); - public static List sendFrameJSONProvider = new List(); - public static List receivedFrameJSONRequester = new List(); - public static string srAnswerMessageType = ""; - public static ISubmodel returnBoringSbmodel() - { - //IIdentifiable _boringSMID = new IIdentifiable(); - string _boringSMID = "www.company.com/ids/sm/3145_4121_8002_1792"; - //Submodel _boringSubmodel = new Submodel(); - ISubmodel _boringSubmodel = Program.env[0].AasEnv.FindSubmodelById(_boringSMID); - //return Program.env[0].AasEnv.FindSubmodelById(_boringSMID); - return _boringSubmodel; - } - public static bool operation_sendFrame(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: memory, connect - // inputVariable reference frame proposal: collection - // inputVariable reference submodel - // outputVariable reference property sendFrameJSON - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 3 && op.OutputVariables.Count != 1) - { - return false; - } - - Property protocol = null; - SubmodelElementCollection refFrame = null; - Submodel refSubmodel = null; - Property sendFrameJSON = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property) - { - protocol = (inputRef as Property); - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection) - refFrame = refElement as SubmodelElementCollection; - if (refElement is Submodel) - refSubmodel = refElement as Submodel; - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is Property) - sendFrameJSON = refElement as Property; - } - - if (protocol.Value != "memory" && protocol.Value != "connect") - return false; - - if (boringSubmodel == null) - return false; - I40MessageHelper _i40MessageHelper = new I40MessageHelper(); - I40Message_Interaction newBiddingMessage = _i40MessageHelper.createBiddingMessage(Program.connectNodeName, - boringSubmodelFrame.sender.identification.id, - boringSubmodelFrame.sender.role.name, "BoringProvider", "proposal", - "RESTAPI", boringSubmodelFrame.replyBy, boringSubmodelFrame.conversationId, Program.count); - - Program.count = Program.count + 1; - - //Submodel _boringSubmodel = new Submodel(); - ISubmodel _boringSubmodel = returnBoringSbmodel(); - newBiddingMessage.interactionElements.Add(_boringSubmodel); - - string frame = JsonConvert.SerializeObject(newBiddingMessage, Newtonsoft.Json.Formatting.Indented); - sendFrameJSON.Value = frame; - - boringSubmodel = null; - - // Console.WriteLine(frame); - - if (auto.name == "automatonServiceRequester") - { - switch (protocol.Value) - { - case "memory": - receivedFrameJSONProvider.Add(frame); - break; - case "connect": - sendFrameJSONRequester.Add(frame); - break; - } - } - if (auto.name == "automatonServiceProvider") - { - switch (protocol.Value) - { - case "memory": - receivedFrameJSONRequester.Add(frame); - break; - case "connect": - sendFrameJSONProvider.Add(frame); - break; - } - } - - return true; - } - - public static bool operation_sendI40message(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: i40connect - // inputVariable property protocolServer: URL - // alternative 1 - // inputVariable reference submodel - // alternative 2 - // outputVariable reference messageType - // alternatives end - // outputVariable reference property sendFrameJSON - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 3 && op.OutputVariables.Count != 1) - { - return false; - } - - Property protocol = null; - Property protocolServer = null; - Submodel refSubmodel = null; - Property messageType = null; - Property sendFrameJSON = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property p1) - { - if (p1.IdShort == "messageType") - messageType = p1; - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property p) - { - if (p.IdShort == "protocol") - protocol = p; - if (p.IdShort == "protocolServer") - protocolServer = p; - } - if (refElement is Submodel s) - { - refSubmodel = s; - } - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is Property p) - { - sendFrameJSON = refElement as Property; - } - } - - if (protocol.Value != "memory" && protocol.Value != "i40connect") - return false; - - string frame = ""; - if (refSubmodel != null) - { - if (boringSubmodel == null) - return false; - I40MessageHelper _i40MessageHelper = new I40MessageHelper(); - I40Message_Interaction newBiddingMessage = _i40MessageHelper.createBiddingMessage(Program.connectNodeName, - boringSubmodelFrame.sender.identification.id, - boringSubmodelFrame.sender.role.name, "BoringProvider", "proposal", - "RESTAPI", boringSubmodelFrame.replyBy, boringSubmodelFrame.conversationId, Program.count); - - Program.count = Program.count + 1; - - //Submodel _boringSubmodel = new Submodel(); - ISubmodel _boringSubmodel = returnBoringSbmodel(); - newBiddingMessage.interactionElements.Add(_boringSubmodel); - - frame = JsonConvert.SerializeObject(newBiddingMessage, Newtonsoft.Json.Formatting.Indented); - sendFrameJSON.Value = frame; - - boringSubmodel = null; - } - else - { - if (messageType.Value == "informConfirm") - { - Console.WriteLine("The Service requester has sent the accept proposal"); - I40MessageHelper _i40MessageHelper = new I40MessageHelper(); - I40Message_Interaction newBiddingMessage = _i40MessageHelper.createBiddingMessage(Program.connectNodeName, - boringSubmodelFrame.sender.identification.id, - boringSubmodelFrame.sender.role.name, "BoringProvider", "informConfirm", - "RESTAPI", boringSubmodelFrame.replyBy, boringSubmodelFrame.conversationId, Program.count); - - Program.count = Program.count + 1; - - frame = JsonConvert.SerializeObject(newBiddingMessage, Newtonsoft.Json.Formatting.Indented); - sendFrameJSONProvider.Add(frame); - Console.WriteLine("The informConfirm is sent to the service Requesters"); - } - } - - // Console.WriteLine(frame); - if (frame != "") - { - if (auto.name == "automatonServiceRequester") - { - switch (protocol.Value) - { - case "memory": - receivedFrameJSONProvider.Add(frame); - break; - case "i40connect": - sendFrameJSONRequester.Add(frame); - break; - } - } - if (auto.name == "automatonServiceProvider") - { - switch (protocol.Value) - { - case "memory": - receivedFrameJSONRequester.Add(frame); - break; - case "i40connect": - sendFrameJSONProvider.Add(frame); - break; - } - } - } - - return true; - } - - public static bool operation_processRequesterResponse(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property protocol: memory, connect - // inputVariable reference frame proposal: collection - // inputVariable reference submodel - // outputVariable reference property sendFrameJSON - - if (auto.name == debugAutomaton) - { - } - if (srAnswerMessageType == "acceptProposal") - { - Console.WriteLine("The Service requester has sent the accept proposal"); - I40MessageHelper _i40MessageHelper = new I40MessageHelper(); - I40Message_Interaction newBiddingMessage = _i40MessageHelper.createBiddingMessage(Program.connectNodeName, - boringSubmodelFrame.sender.identification.id, - boringSubmodelFrame.sender.role.name, "BoringProvider", "informConfirm", - "RESTAPI", boringSubmodelFrame.replyBy, boringSubmodelFrame.conversationId, Program.count); - - Program.count = Program.count + 1; - - string frame = JsonConvert.SerializeObject(newBiddingMessage, Newtonsoft.Json.Formatting.Indented); - sendFrameJSONProvider.Add(frame); - Console.WriteLine("The informConfirm is sent to the service Requesters"); - - } - else if (srAnswerMessageType == "rejectProposal") - { - Console.WriteLine("The Service requester has sent the reject proposal"); - } - return true; - } - - public static bool operation_clear(Operation op, i40LanguageAutomaton auto) - { - // outputVariables are references to collections - // alle elements will be removed from collections - - if (auto.name == debugAutomaton) - { - } - - if (op.OutputVariables.Count == 0) - { - return false; - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (outputRef is ReferenceElement) - { - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection) - { - var refSMEC = refElement as SubmodelElementCollection; - List list = new List(); - foreach (var sme in refSMEC.Value) - { - list.Add(sme); - } - foreach (var sme2 in list) - { - refSMEC.Value.Remove(sme2); - treeChanged = true; - } - } - if (refElement is Property p) - { - p.Value = ""; - } - } - } - - return true; - } - - public static bool operation_checkCollection(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property checkType: isEmpty, isNotEmpty; - // inputVariable reference collection proposal - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 2 && op.OutputVariables.Count != 0) - { - return false; - } - - Property checkType = null; - SubmodelElementCollection refCollection = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property) - { - checkType = (inputRef as Property); - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection) - refCollection = refElement as SubmodelElementCollection; - } - - int count = refCollection.Value.Count; - - switch (checkType.IdShort) - { - case "isEmpty": - return (count == 0); - case "isNotEmpty": - return (count != 0); - } - - return false; - } - - public static bool operation_check(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property checkType: isEmpty, isNotEmpty; - // inputVariable reference collection proposal - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 3 && op.OutputVariables.Count != 0) - { - return false; - } - - Property checkType = null; - Property argument1 = null; - Property argument2 = null; - SubmodelElementCollection refCollection = null; - Property refProperty = null; - int count = 0; - string value = ""; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property) - { - if (count == 0) - checkType = (inputRef as Property); - if (count == 1) - argument1 = (inputRef as Property); - if (count == 2) - argument2 = (inputRef as Property); - count++; - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property) - { - refProperty = refElement as Property; - if (count == 1) - argument1 = (refProperty as Property); - if (count == 2) - argument2 = (refProperty as Property); - } - if (refElement is SubmodelElementCollection) - { - refCollection = refElement as SubmodelElementCollection; - } - count++; - } - - if (checkType == null || argument1 == null || argument2 == null) - return false; - - switch (checkType.IdShort) - { - case "isEmpty": - if (refCollection != null) - return (count == 0); - if (argument1 != null) - return (value == ""); - return false; - case "isNotEmpty": - if (refCollection != null) - return (count != 0); - if (argument1 != null) - return (value != ""); - return false; - case "isEqual": - return (argument1.Value == argument2.Value); - case "isNotEqual": - return (argument1.Value != argument2.Value); - } - - return false; - } - - public static bool operation_executeLogic(Operation op, i40LanguageAutomaton auto) - { - // parameter sequence - // inputVariable property i40logic type: 1 - // inputVariable reference property protocol type: 1 - // inputVariable reference collection frame(s): 1..2 - // inputVariable reference collection inputQueue: 1 - // inputVariable reference submodel sub: 0..1 - // inputVariable reference property message: 0..1 - // outputVariable reference collection outputQueue(s): 0..2 - - // alternative 1 - // inputVariable property i40Logic = callForProposal - // inputVariable reference property protocol - // inputVariable reference collection frameProposal - // inputVariable reference submodel proposal - // outputVariable reference collection queueProposal - - // alternative 2 - // inputVariable property i40Logic = evaluateProposal - // inputVariable reference property protocol - // inputVariable reference collection frameAcceptProposal - // inputVariable reference collection frameRejectProposal - // inputVariable reference collection queueProposal - // outputVariable reference collection queueAcceptProposal - // outputVariable reference collection queueRejectProposal - - // alternative 3 - // inputVariable property i40Logic = evaluateInformConfirm - // inputVariable reference property protocol - // inputVariable reference collection frameInformConfirm - // inputVariable reference collection queueInformConfirm - - // alternative 4 - // inputVariable property i40Logic = capabiltyCheck - // inputVariable reference property protocol - // inputVariable reference collection frameNotUnderstood - // inputVariable reference collection queueProposal - // inputVariable reference property proposalMessage - // outputVariable reference collection queueNotUnderstood - - // alternative 5 - // inputVariable property i40Logic = feasibilityCheck - // inputVariable reference property protocol - // inputVariable reference collection frameRefuse - // inputVariable reference property proposalMessage - // outputVariable reference collection queueRefuseProposal - - // alternative 6 - // inputVariable property i40Logic = checkingSchedule - // inputVariable reference property protocol - // inputVariable reference collection frameRefuse - // inputVariable reference property proposalMessage - // outputVariable reference collection queueRefuseProposal - - // alternative 7 - // inputVariable property i40Logic = PriceCalculation - // inputVariable reference property protocol - // inputVariable reference collection frameProposal - // inputVariable reference property proposalMessage - // outputVariable reference collection queueProposal - - // alternative 8 - // inputVariable property i40Logic = WaitingForServiceRequesterAnswer - // inputVariable reference property protocol - // inputVariable reference collection frameAcceptProposal - // inputVariable reference collection frameRejectProposal - // inputVariable reference collection queueSRAnswer - // outputVariable reference collection queueAcceptProposal - // outputVariable reference collection queueRejectProposal - - // alternative 9 - // inputVariable property i40Logic = ServiceProvision - // inputVariable reference property protocol - // inputVariable reference collection frameInfomrConfirm - // outputVariable reference collection queueInfomrConfirm - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count < 4 && op.OutputVariables.Count > 2) - { - return false; - } - - // inputVariable property i40logic type: 1 - // inputVariable reference property protocol type: 1 - // inputVariable reference collection frame(s): 1..2 - // inputVariable reference collection inputQueue: 1 - // inputVariable reference submodel sub: 0..1 - // inputVariable reference property message: 0..1 - // outputVariable reference collection outputQueue(s): 0..2 - Property i40Logic = null; - Property protocol = null; - SubmodelElementCollection frame1 = null; - SubmodelElementCollection frame2 = null; - SubmodelElementCollection inQueue = null; - Submodel sub = null; - SubmodelElementCollection proposalMessage = null; - SubmodelElementCollection outQueue1 = null; - SubmodelElementCollection outQueue2 = null; - - SubmodelElementCollection refCollection = null; - Property refProperty = null; - - string state = "i40logic"; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property p) - { - switch (p.IdShort) - { - case "i40Logic": - i40Logic = p; - state = "protocol"; - break; - } - // Debug - switch (i40Logic?.Value) - { - case "callForProposal": - break; - case "evaluateProposal": - break; - case "evaluateInformConfirm": - break; - case "capabilityCheck": - break; - case "feasibilityCheck": - break; - case "checkingSchedule": - break; - case "PriceCalculation": - break; - case "ServiceProvision": - break; - case "WaitingForServiceRequesterAnswer": - break; - } - continue; - } - - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property) - { - refProperty = refElement as Property; - switch (refProperty.IdShort) - { - case "protocol": - protocol = refProperty; - state = "frame1"; - break; - } - continue; - } - if (refElement is Submodel) - { - if (state == "submodel") - { - sub = refElement as Submodel; - state = "outQueue1"; - } - continue; - } - if (refElement is SubmodelElementCollection) - { - refCollection = refElement as SubmodelElementCollection; - if (refCollection.IdShort == "proposalMessage") - { - proposalMessage = refCollection; - state = "outQueue1"; - continue; - } - - switch (i40Logic?.Value) - { - case "callForProposal": - switch (state) - { - case "frame1": - frame1 = refCollection; - state = "submodel"; - break; - case "outQueue1": - outQueue1 = refCollection; - state = ""; - break; - } - break; - case "evaluateProposal": - case "WaitingForServiceRequesterAnswer": - switch (state) - { - case "frame1": - frame1 = refCollection; - state = "frame2"; - break; - case "frame2": - frame2 = refCollection; - state = "inQueue"; - break; - case "inQueue": - inQueue = refCollection; - state = "outQueue1"; - break; - } - break; - case "evaluateInformConfirm": - switch (state) - { - case "frame1": - frame1 = refCollection; - state = "inQueue"; - break; - case "inQueue": - inQueue = refCollection; - state = ""; - break; - } - break; - case "capabilityCheck": - switch (state) - { - case "frame1": - frame1 = refCollection; - state = "inQueue"; - break; - case "inQueue": - inQueue = refCollection; - state = ""; - break; - } - break; - case "feasibilityCheck": - case "checkingSchedule": - case "PriceCalculation": - switch (state) - { - case "frame1": - frame1 = refCollection; - state = "message"; - break; - } - break; - case "ServiceProvision": - inQueue = refCollection; - state = "outQueue1"; - break; - } - continue; - } - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection) - { - refCollection = refElement as SubmodelElementCollection; - switch (i40Logic?.Value) - { - case "callForProposal": - case "capabilityCheck": - case "feasibilityCheck": - case "checkingSchedule": - case "PriceCalculation": - case "ServiceProvision": - switch (state) - { - case "outQueue1": - outQueue1 = refCollection; - state = ""; - break; - } - break; - case "evaluateProposal": - case "WaitingForServiceRequesterAnswer": - switch (state) - { - case "outQueue1": - outQueue1 = refCollection; - state = "outQueue2"; - break; - case "outQueue2": - outQueue2 = refCollection; - state = ""; - break; - } - break; - } - continue; - } - } - - // Execute operation - SubmodelElementCollection smcSubmodel = null; - - switch (i40Logic?.Value) - { - case "callForProposal": - // Harish, please add correct code here - smcSubmodel = new SubmodelElementCollection(); - smcSubmodel.IdShort = "callForProposal"; - foreach (var sme in sub.SubmodelElements) - { - smcSubmodel.Value.Add(sme); - treeChanged = true; - } - outQueue1.Value.Add(smcSubmodel); - return true; - case "evaluateProposal": - // Harish, please add correct code here - foreach (var sme in inQueue.Value) - { - outQueue1.Value.Add(sme); - } - inQueue.Value.Clear(); - treeChanged = true; - return true; - case "WaitingForServiceRequesterAnswer": - // Harish, please add correct code here - foreach (var sme in inQueue.Value) - { - outQueue1.Value.Add(smcSubmodel); - } - inQueue.Value.Clear(); - treeChanged = true; - return true; - case "ServiceProvision": - if (inQueue.Value.Count != 0) - { - outQueue1.Value.Add(inQueue); - // inQueue.Value.Clear(); - treeChanged = true; - } - return true; - case "evaluateInformConfirm": - return true; - case "capabilityCheck": - return true; - case "feasibilityCheck": - return true; - case "checkingSchedule": - return true; - case "PriceCalculation": - outQueue1.Value.Add(proposalMessage); - treeChanged = true; - return true; - } - - return false; - } - - public static List i40frameRequesterSendBuffer = new List(); - public static List i40frameProviderSendBuffer = new List(); - - static void i40frameSend(string message, string protocol, i40LanguageAutomaton auto) - { - if (protocol == "memory") - { - if (auto.name == "automatonServiceRequester") - { - i40frameRequesterSendBuffer.Add(message); - } - if (auto.name == "automatonServiceProvider") - { - i40frameProviderSendBuffer.Add(message); - } - } - } - - static string i40frameReceive(string protocol, i40LanguageAutomaton auto) - { - string message = ""; - - if (protocol == "memory") - { - if (auto.name == "automatonServiceRequester") - { - if (i40frameProviderSendBuffer.Count > 0) - { - message = i40frameProviderSendBuffer[0]; - i40frameProviderSendBuffer.RemoveAt(0); - } - } - if (auto.name == "automatonServiceProvider") - { - if (i40frameRequesterSendBuffer.Count > 0) - { - message = i40frameRequesterSendBuffer[0]; - i40frameRequesterSendBuffer.RemoveAt(0); - } - } - } - - return message; - } - - public static bool operation_sendI40frame(Operation op, i40LanguageAutomaton auto) - { - // inputVariable reference property protocol - // inputVariable reference collection outputQueue - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 2) - { - return false; - } - - Property protocol = null; - SubmodelElementCollection outQueue = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property p) - { - protocol = p; - continue; - } - if (refElement is SubmodelElementCollection) - { - outQueue = refElement as SubmodelElementCollection; - continue; - } - } - - if (protocol != null & outQueue != null) - { - // Harish, please add correct code here - i40frameSend(JsonConvert.SerializeObject(outQueue, Newtonsoft.Json.Formatting.Indented), protocol.Value, auto); - } - - return false; - } - - public static bool operation_receiveI40frame(Operation op, i40LanguageAutomaton auto) - { - // inputVariable reference property protocol - // inputVariable reference collection inputQueue - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 2) - { - return false; - } - - Property protocol = null; - SubmodelElementCollection inQueue = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is Property p) - { - protocol = p; - continue; - } - if (refElement is SubmodelElementCollection) - { - inQueue = refElement as SubmodelElementCollection; - continue; - } - } - - if (protocol != null & inQueue != null) - { - // Harish, please add correct code here - - SubmodelElementCollection smc = null; - try - { - smc = Newtonsoft.Json.JsonConvert.DeserializeObject - (i40frameReceive(protocol.Value, auto), new AdminShellConverters.JsonAasxConverter("modelType", "name")); - if (smc != null) - { - foreach (var sme in smc.Value) - { - inQueue.Value.Add(sme); - treeChanged = true; - } - } - } - catch - { } - } - - return false; - } - public static bool operation_calculate(Operation op, i40LanguageAutomaton auto) - { - // inputVariable property checkType: isEmpty, isNotEmpty; - // inputVariable reference collection proposal - - if (auto.name == debugAutomaton) - { - } - - if (op.InputVariables.Count != 2 && op.OutputVariables.Count != 1) - { - return false; - } - - Property operation = null; - SubmodelElementCollection inputCollection = null; - Property outputProperty = null; - SubmodelElementCollection outputCollection = null; - - foreach (var input in op.InputVariables) - { - var inputRef = input.Value; - if (inputRef is Property) - { - operation = (inputRef as Property); - continue; - } - if (!(inputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((inputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += inputRef.IdShort + " not found! "; - if (refElement is SubmodelElementCollection) - { - inputCollection = refElement as SubmodelElementCollection; - } - } - - foreach (var output in op.OutputVariables) - { - var outputRef = output.Value; - if (!(outputRef is ReferenceElement)) - return false; - var refElement = Program.env[0].AasEnv.FindReferableByReference((outputRef as ReferenceElement).GetModelReference()); - if (refElement == null) - auto.getErrors += outputRef.IdShort + " not found! "; - if (refElement is Property) - { - outputProperty = (refElement as Property); - continue; - } - if (refElement is SubmodelElementCollection) - { - outputCollection = (refElement as SubmodelElementCollection); - continue; - } - } - - if (operation == null || inputCollection == null || (outputProperty == null && outputCollection == null)) - return false; - - switch (operation.IdShort) - { - case "length": - outputProperty.Value = inputCollection.Value.Count.ToString(); - break; - case "getFirst": - if (outputProperty != null) - outputProperty.Value = inputCollection.Value[0].ValueAsText(); - if (outputCollection != null) - { - outputCollection.Value.Add(inputCollection.Value[0]); - } - inputCollection.Value.RemoveAt(0); - break; - } - - return false; - } - } -} diff --git a/src/DataTransferObjects/DataTransferObjects.csproj b/src/DataTransferObjects/DataTransferObjects.csproj index 77c8c8b3f..d53464475 100644 --- a/src/DataTransferObjects/DataTransferObjects.csproj +++ b/src/DataTransferObjects/DataTransferObjects.csproj @@ -1,17 +1,17 @@  - - net6.0 - enable - enable - + + net6.0 + enable + enable + - - false - + + false + - - - + + + diff --git a/src/ExampleClient/ExampleClient.csproj b/src/ExampleClient/ExampleClient.csproj index 5082f9ad6..a8d330362 100644 --- a/src/ExampleClient/ExampleClient.csproj +++ b/src/ExampleClient/ExampleClient.csproj @@ -1,19 +1,19 @@ - - Exe - net6.0 - enable - enable - + + Exe + net6.0 + enable + enable + - - - + + + - - - - + + + + diff --git a/src/IO.Swagger.Lib.V3/Controllers/ConceptDescriptionRepositoryAPIApi.cs b/src/IO.Swagger.Lib.V3/Controllers/ConceptDescriptionRepositoryAPIApi.cs index 6a6afbc36..106fdc5e9 100644 --- a/src/IO.Swagger.Lib.V3/Controllers/ConceptDescriptionRepositoryAPIApi.cs +++ b/src/IO.Swagger.Lib.V3/Controllers/ConceptDescriptionRepositoryAPIApi.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using AasSecurity.Exceptions; using AasxServerStandardBib.Interfaces; using AasxServerStandardBib.Logging; @@ -28,8 +29,8 @@ namespace IO.Swagger.Controllers /// /// /// - [Authorize(AuthenticationSchemes = "AasSecurityAuth")] - [ApiController] + [ Authorize(AuthenticationSchemes = "AasSecurityAuth") ] + [ ApiController ] public class ConceptDescriptionRepositoryAPIApiController : ControllerBase { private readonly IAppLogger _logger; @@ -39,7 +40,8 @@ public class ConceptDescriptionRepositoryAPIApiController : ControllerBase private readonly IPaginationService _paginationService; private readonly IAuthorizationService _authorizationService; - public ConceptDescriptionRepositoryAPIApiController(IAppLogger logger, IBase64UrlDecoderService decoderService, IConceptDescriptionService cdService, IJsonQueryDeserializer jsonQueryDeserializer, IPaginationService paginationService, IAuthorizationService authorizationService) + public ConceptDescriptionRepositoryAPIApiController(IAppLogger logger, IBase64UrlDecoderService decoderService, + IConceptDescriptionService cdService, IJsonQueryDeserializer jsonQueryDeserializer, IPaginationService paginationService, IAuthorizationService authorizationService) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _decoderService = decoderService ?? throw new ArgumentNullException(nameof(decoderService)); @@ -48,6 +50,7 @@ public ConceptDescriptionRepositoryAPIApiController(IAppLogger /// Deletes a Concept Description /// @@ -58,16 +61,16 @@ public ConceptDescriptionRepositoryAPIApiController(IAppLoggerNot Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpDelete] - [Route("/concept-descriptions/{cdIdentifier}")] - [ValidateModelState] - [SwaggerOperation("DeleteConceptDescriptionById")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult DeleteConceptDescriptionById([FromRoute][Required] string cdIdentifier) + [ HttpDelete ] + [ Route("/concept-descriptions/{cdIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("DeleteConceptDescriptionById") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult DeleteConceptDescriptionById([ FromRoute ] [ Required ] string cdIdentifier) { var decodedCdIdentifier = _decoderService.Decode("cdIdentifier", cdIdentifier); @@ -91,24 +94,25 @@ public virtual IActionResult DeleteConceptDescriptionById([FromRoute][Required] /// Forbidden /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/concept-descriptions")] - [ValidateModelState] - [SwaggerOperation("GetAllConceptDescriptions")] + [ HttpGet ] + [ Route("/concept-descriptions") ] + [ ValidateModelState ] + [ SwaggerOperation("GetAllConceptDescriptions") ] //[SwaggerResponse(statusCode: 200, type: typeof(GetConceptDescriptionsResult), description: "Requested Concept Descriptions")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Concept Descriptions")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllConceptDescriptions([FromQuery] string idShort, [FromQuery] string isCaseOf, [FromQuery] string dataSpecificationRef, [FromQuery] int? limit, [FromQuery] string cursor) + [ SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Concept Descriptions") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetAllConceptDescriptions([ FromQuery ] string idShort, [ FromQuery ] string isCaseOf, [ FromQuery ] string dataSpecificationRef, + [ FromQuery ] int? limit, [ FromQuery ] string cursor) { _logger.LogInformation($"Received request to get all the concept descriptions."); var reqIsCaseOf = _jsonQueryDeserializer.DeserializeReference("isCaseOf", isCaseOf); var reqDataSpecificationRef = _jsonQueryDeserializer.DeserializeReference("dataSpecificationRef", dataSpecificationRef); - + List cdList = new List(); - if(reqDataSpecificationRef != null) + if (reqDataSpecificationRef != null) cdList = _cdService.GetAllConceptDescriptions(idShort, reqIsCaseOf, reqDataSpecificationRef); var authResult = _authorizationService.AuthorizeAsync(User, cdList, "SecurityPolicy").Result; @@ -135,17 +139,17 @@ public virtual IActionResult GetAllConceptDescriptions([FromQuery] string idShor /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/concept-descriptions/{cdIdentifier}")] - [ValidateModelState] - [SwaggerOperation("GetConceptDescriptionById")] - [SwaggerResponse(statusCode: 200, type: typeof(ConceptDescription), description: "Requested Concept Description")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetConceptDescriptionById([FromRoute][Required] string cdIdentifier) + [ HttpGet ] + [ Route("/concept-descriptions/{cdIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("GetConceptDescriptionById") ] + [ SwaggerResponse(statusCode: 200, type: typeof(ConceptDescription), description: "Requested Concept Description") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetConceptDescriptionById([ FromRoute ] [ Required ] string cdIdentifier) { var decodedCdIdentifier = _decoderService.Decode("cdIdentifier", cdIdentifier); @@ -162,6 +166,7 @@ public virtual IActionResult GetConceptDescriptionById([FromRoute][Required] str throw new NotAllowed(failedReason.Message); } } + return new ObjectResult(output); } @@ -175,17 +180,19 @@ public virtual IActionResult GetConceptDescriptionById([FromRoute][Required] str /// Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request. /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpPost] - [Route("/concept-descriptions")] - [ValidateModelState] - [SwaggerOperation("PostConceptDescription")] - [SwaggerResponse(statusCode: 201, type: typeof(ConceptDescription), description: "Concept Description created successfully")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 409, type: typeof(Result), description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PostConceptDescription([FromBody] ConceptDescription body) + [ HttpPost ] + [ Route("/concept-descriptions") ] + [ ValidateModelState ] + [ SwaggerOperation("PostConceptDescription") ] + [ SwaggerResponse(statusCode: 201, type: typeof(ConceptDescription), description: "Concept Description created successfully") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 409, type: typeof(Result), + description: + "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PostConceptDescription([ FromBody ] ConceptDescription body) { var output = _cdService.CreateConceptDescription(body); @@ -203,16 +210,16 @@ public virtual IActionResult PostConceptDescription([FromBody] ConceptDescriptio /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpPut] - [Route("/concept-descriptions/{cdIdentifier}")] - [ValidateModelState] - [SwaggerOperation("PutConceptDescriptionById")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PutConceptDescriptionById([FromBody] ConceptDescription body, [FromRoute][Required] string cdIdentifier) + [ HttpPut ] + [ Route("/concept-descriptions/{cdIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("PutConceptDescriptionById") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PutConceptDescriptionById([ FromBody ] ConceptDescription body, [ FromRoute ] [ Required ] string cdIdentifier) { var decodedCdId = _decoderService.Decode("cdIdentifier", cdIdentifier); @@ -221,4 +228,4 @@ public virtual IActionResult PutConceptDescriptionById([FromBody] ConceptDescrip return NoContent(); } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Lib.V3/IO.Swagger.Lib.V3.csproj b/src/IO.Swagger.Lib.V3/IO.Swagger.Lib.V3.csproj index 8270939b5..19118d141 100644 --- a/src/IO.Swagger.Lib.V3/IO.Swagger.Lib.V3.csproj +++ b/src/IO.Swagger.Lib.V3/IO.Swagger.Lib.V3.csproj @@ -1,33 +1,33 @@ - - IO.Swagger - IO.Swagger - net6.0 - true - true - IO.Swagger.Lib.V3 - IO.Swagger - Library - - - false - - - - - - - - - - - - - - - - - - - + + IO.Swagger + IO.Swagger + net6.0 + true + true + IO.Swagger.Lib.V3 + IO.Swagger + Library + + + false + + + + + + + + + + + + + + + + + + + diff --git a/src/IO.Swagger.Lib.V3/Models/BaseOperationResult.cs b/src/IO.Swagger.Lib.V3/Models/BaseOperationResult.cs index cf8622f67..c9130a745 100644 --- a/src/IO.Swagger.Lib.V3/Models/BaseOperationResult.cs +++ b/src/IO.Swagger.Lib.V3/Models/BaseOperationResult.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using System; using System.Linq; using System.IO; @@ -19,25 +20,25 @@ using Newtonsoft.Json; namespace IO.Swagger.Models -{ +{ /// /// /// - [DataContract] + [ DataContract ] public partial class BaseOperationResult : Result, IEquatable - { + { /// /// Gets or Sets ExecutionState /// - [DataMember(Name="executionState")] + [ DataMember(Name = "executionState") ] public ExecutionState ExecutionState { get; set; } /// /// Gets or Sets Success /// - [DataMember(Name="success")] + [ DataMember(Name = "success") ] public bool? Success { get; set; } /// @@ -58,7 +59,7 @@ public override string ToString() /// Returns the JSON string presentation of the object /// /// JSON string presentation of the object - public new string ToJson() + public new string ToJson() { return JsonConvert.SerializeObject(this, Formatting.Indented); } @@ -72,7 +73,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((BaseOperationResult)obj); + return obj.GetType() == GetType() && Equals((BaseOperationResult) obj); } /// @@ -85,12 +86,12 @@ public bool Equals(BaseOperationResult other) if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return + return ( ExecutionState == other.ExecutionState || ExecutionState != null && ExecutionState.Equals(other.ExecutionState) - ) && + ) && ( Success == other.Success || Success != null && @@ -108,16 +109,17 @@ public override int GetHashCode() { var hashCode = 41; // Suitable nullity checks etc, of course :) - if (ExecutionState != null) + if (ExecutionState != null) hashCode = hashCode * 59 + ExecutionState.GetHashCode(); - if (Success != null) + if (Success != null) hashCode = hashCode * 59 + Success.GetHashCode(); return hashCode; } } #region Operators - #pragma warning disable 1591 + +#pragma warning disable 1591 public static bool operator ==(BaseOperationResult left, BaseOperationResult right) { @@ -129,7 +131,8 @@ public override int GetHashCode() return !Equals(left, right); } - #pragma warning restore 1591 +#pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Lib.V3/Models/Message.cs b/src/IO.Swagger.Lib.V3/Models/Message.cs index 23c8c5f9b..c784b3812 100644 --- a/src/IO.Swagger.Lib.V3/Models/Message.cs +++ b/src/IO.Swagger.Lib.V3/Models/Message.cs @@ -7,92 +7,89 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using System; -using System.Linq; -using System.IO; using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; using Newtonsoft.Json; namespace IO.Swagger.Models -{ +{ /// /// /// - [DataContract] + [ DataContract ] public partial class Message : IEquatable - { + { /// /// Gets or Sets Code /// - [StringLength(32, MinimumLength=1)] - [DataMember(Name="code")] + [ StringLength(32, MinimumLength = 1) ] + [ DataMember(Name = "code") ] public string Code { get; set; } /// /// Gets or Sets CorrelationId /// - [StringLength(128, MinimumLength=1)] - [DataMember(Name="correlationId")] + [ StringLength(128, MinimumLength = 1) ] + [ DataMember(Name = "correlationId") ] public string CorrelationId { get; set; } /// /// Gets or Sets MessageType /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [ JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter)) ] public enum MessageTypeEnum { /// /// Enum UndefinedEnum for Undefined /// - [EnumMember(Value = "Undefined")] - UndefinedEnum = 0, + [ EnumMember(Value = "Undefined") ] UndefinedEnum = 0, + /// /// Enum InfoEnum for Info /// - [EnumMember(Value = "Info")] - InfoEnum = 1, + [ EnumMember(Value = "Info") ] InfoEnum = 1, + /// /// Enum WarningEnum for Warning /// - [EnumMember(Value = "Warning")] - WarningEnum = 2, + [ EnumMember(Value = "Warning") ] WarningEnum = 2, + /// /// Enum ErrorEnum for Error /// - [EnumMember(Value = "Error")] - ErrorEnum = 3, + [ EnumMember(Value = "Error") ] ErrorEnum = 3, + /// /// Enum ExceptionEnum for Exception /// - [EnumMember(Value = "Exception")] - ExceptionEnum = 4 } + [ EnumMember(Value = "Exception") ] ExceptionEnum = 4 + } /// /// Gets or Sets MessageType /// - [DataMember(Name="messageType")] + [ DataMember(Name = "messageType") ] public MessageTypeEnum? MessageType { get; set; } /// /// Gets or Sets Text /// - [DataMember(Name="text")] + [ DataMember(Name = "text") ] public string Text { get; set; } /// /// Gets or Sets Timestamp /// - [RegularExpression("/^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|\\+00:00|-00:00)$/")] - [DataMember(Name="timestamp")] + [ RegularExpression( + "/^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|\\+00:00|-00:00)$/") ] + [ DataMember(Name = "timestamp") ] public string Timestamp { get; set; } /// @@ -130,7 +127,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Message)obj); + return obj.GetType() == GetType() && Equals((Message) obj); } /// @@ -143,27 +140,27 @@ public bool Equals(Message other) if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return + return ( Code == other.Code || Code != null && Code.Equals(other.Code) - ) && + ) && ( CorrelationId == other.CorrelationId || CorrelationId != null && CorrelationId.Equals(other.CorrelationId) - ) && + ) && ( MessageType == other.MessageType || MessageType != null && MessageType.Equals(other.MessageType) - ) && + ) && ( Text == other.Text || Text != null && Text.Equals(other.Text) - ) && + ) && ( Timestamp == other.Timestamp || Timestamp != null && @@ -181,22 +178,23 @@ public override int GetHashCode() { var hashCode = 41; // Suitable nullity checks etc, of course :) - if (Code != null) + if (Code != null) hashCode = hashCode * 59 + Code.GetHashCode(); - if (CorrelationId != null) + if (CorrelationId != null) hashCode = hashCode * 59 + CorrelationId.GetHashCode(); - if (MessageType != null) + if (MessageType != null) hashCode = hashCode * 59 + MessageType.GetHashCode(); - if (Text != null) + if (Text != null) hashCode = hashCode * 59 + Text.GetHashCode(); - if (Timestamp != null) + if (Timestamp != null) hashCode = hashCode * 59 + Timestamp.GetHashCode(); return hashCode; } } #region Operators - #pragma warning disable 1591 + +#pragma warning disable 1591 public static bool operator ==(Message left, Message right) { @@ -208,7 +206,8 @@ public override int GetHashCode() return !Equals(left, right); } - #pragma warning restore 1591 +#pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Lib.V3/Models/Result.cs b/src/IO.Swagger.Lib.V3/Models/Result.cs index 709aab1df..db61b13e2 100644 --- a/src/IO.Swagger.Lib.V3/Models/Result.cs +++ b/src/IO.Swagger.Lib.V3/Models/Result.cs @@ -7,30 +7,27 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using System; using System.Linq; -using System.IO; using System.Text; -using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; using Newtonsoft.Json; namespace IO.Swagger.Models -{ +{ /// /// /// - [DataContract] + [ DataContract ] public partial class Result : IEquatable - { + { /// /// Gets or Sets Messages /// - [DataMember(Name="messages")] + [ DataMember(Name = "messages") ] public List Messages { get; set; } /// @@ -64,7 +61,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Result)obj); + return obj.GetType() == GetType() && Equals((Result) obj); } /// @@ -77,12 +74,12 @@ public bool Equals(Result other) if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return - ( - Messages == other.Messages || - Messages != null && - Messages.SequenceEqual(other.Messages) - ); + return + ( + Messages == other.Messages || + Messages != null && + Messages.SequenceEqual(other.Messages) + ); } /// @@ -95,14 +92,15 @@ public override int GetHashCode() { var hashCode = 41; // Suitable nullity checks etc, of course :) - if (Messages != null) + if (Messages != null) hashCode = hashCode * 59 + Messages.GetHashCode(); return hashCode; } } #region Operators - #pragma warning disable 1591 + +#pragma warning disable 1591 public static bool operator ==(Result left, Result right) { @@ -114,7 +112,8 @@ public override int GetHashCode() return !Equals(left, right); } - #pragma warning restore 1591 +#pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Lib.V3/SerializationModifiers/Mappers/ValueMappers/ResponseValueTransformer.cs b/src/IO.Swagger.Lib.V3/SerializationModifiers/Mappers/ValueMappers/ResponseValueTransformer.cs index 0f720361b..b2e96d950 100644 --- a/src/IO.Swagger.Lib.V3/SerializationModifiers/Mappers/ValueMappers/ResponseValueTransformer.cs +++ b/src/IO.Swagger.Lib.V3/SerializationModifiers/Mappers/ValueMappers/ResponseValueTransformer.cs @@ -28,11 +28,11 @@ public IDTO TransformAnnotatedRelationshipElement(IAnnotatedRelationshipElement annotations = new List(); foreach (var element in that.Annotations) { - annotations.Add((ISubmodelElementValue)Transform(element)); + annotations.Add((ISubmodelElementValue) Transform(element)); } } - return new AnnotatedRelationshipElementValue(that.IdShort, (ReferenceDTO)Transform(that.First), (ReferenceDTO)Transform(that.Second), annotations); + return new AnnotatedRelationshipElementValue(that.IdShort, (ReferenceDTO) Transform(that.First), (ReferenceDTO) Transform(that.Second), annotations); } public IDTO TransformAssetAdministrationShell(IAssetAdministrationShell that) @@ -47,7 +47,7 @@ public IDTO TransformAssetInformation(IAssetInformation that) public IDTO TransformBasicEventElement(IBasicEventElement that) { - return new BasicEventElementValue(that.IdShort, (ReferenceDTO)Transform(that.Observed)); + return new BasicEventElementValue(that.IdShort, (ReferenceDTO) Transform(that.Observed)); } public IDTO TransformBlob(IBlob that) @@ -83,11 +83,11 @@ public IDTO TransformEntity(IEntity that) statements = new List(); foreach (var element in that.Statements) { - statements.Add((ISubmodelElementValue)Transform(element)); + statements.Add((ISubmodelElementValue) Transform(element)); } } - return new EntityValue(that.IdShort, that.EntityType, statements, that.GlobalAssetId); + return new EntityValue(that.IdShort, that.EntityType, statements, that.GlobalAssetId); } public IDTO TransformEnvironment(IEnvironment that) @@ -119,7 +119,7 @@ internal List TransformKeyList(List keyList) output = new List(); foreach (var key in keyList) { - output.Add((KeyDTO)Transform(key)); + output.Add((KeyDTO) Transform(key)); } } @@ -168,6 +168,7 @@ public IDTO TransformMultiLanguageProperty(IMultiLanguageProperty that) { langStrings.Add(new KeyValuePair(langString.Language, langString.Text)); } + return new MultiLanguagePropertyValue(that.IdShort, langStrings); } @@ -181,7 +182,7 @@ public IDTO TransformOperation(IOperation that) inputVariables = new List(); foreach (var inputVariable in that.InputVariables) { - inputVariables.Add((ISubmodelElementValue)Transform(inputVariable)); + inputVariables.Add((ISubmodelElementValue) Transform(inputVariable)); } } @@ -190,7 +191,7 @@ public IDTO TransformOperation(IOperation that) outputVariables = new List(); foreach (var outputVariable in that.OutputVariables) { - outputVariables.Add((ISubmodelElementValue)Transform(outputVariable)); + outputVariables.Add((ISubmodelElementValue) Transform(outputVariable)); } } @@ -199,7 +200,7 @@ public IDTO TransformOperation(IOperation that) inoutputVariables = new List(); foreach (var inoutputVariable in that.InoutputVariables) { - inoutputVariables.Add((ISubmodelElementValue)Transform(inoutputVariable)); + inoutputVariables.Add((ISubmodelElementValue) Transform(inoutputVariable)); } } @@ -228,17 +229,17 @@ public IDTO TransformRange(IRange that) public IDTO TransformReference(IReference that) { - return new ReferenceDTO(that.Type, TransformKeyList(that.Keys), (ReferenceDTO)Transform(that.ReferredSemanticId)); + return new ReferenceDTO(that.Type, TransformKeyList(that.Keys), (ReferenceDTO) Transform(that.ReferredSemanticId)); } public IDTO TransformReferenceElement(IReferenceElement that) { - return new ReferenceElementValue(that.IdShort, (ReferenceDTO)Transform(that.Value)); + return new ReferenceElementValue(that.IdShort, (ReferenceDTO) Transform(that.Value)); } public IDTO TransformRelationshipElement(IRelationshipElement that) { - return new RelationshipElementValue(that.IdShort, (ReferenceDTO)Transform(that.First), (ReferenceDTO)Transform(that.Second)); + return new RelationshipElementValue(that.IdShort, (ReferenceDTO) Transform(that.First), (ReferenceDTO) Transform(that.Second)); } public IDTO TransformResource(IResource that) @@ -259,7 +260,7 @@ public IDTO TransformSubmodel(ISubmodel that) submodelElements = new List(); foreach (var element in that.SubmodelElements) { - submodelElements.Add((ISubmodelElementValue)Transform(element)); + submodelElements.Add((ISubmodelElementValue) Transform(element)); } } @@ -274,7 +275,7 @@ public IDTO TransformSubmodelElementCollection(ISubmodelElementCollection that) value = new List(); foreach (var element in that.Value) { - value.Add((ISubmodelElementValue)Transform(element)); + value.Add((ISubmodelElementValue) Transform(element)); } } @@ -289,7 +290,7 @@ public IDTO TransformSubmodelElementList(ISubmodelElementList that) value = new List(); foreach (var element in that.Value) { - value.Add((ISubmodelElementValue)Transform(element)); + value.Add((ISubmodelElementValue) Transform(element)); } } @@ -306,4 +307,4 @@ public IDTO TransformValueReferencePair(IValueReferencePair that) throw new System.NotImplementedException(); } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Attributes/ValidateModelStateAttribute.cs b/src/IO.Swagger.Registry.Lib.V3/Attributes/ValidateModelStateAttribute.cs index 877abe8ca..3435d13c2 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Attributes/ValidateModelStateAttribute.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Attributes/ValidateModelStateAttribute.cs @@ -27,7 +27,7 @@ public override void OnActionExecuting(ActionExecutingContext context) object args = null; if (context.ActionArguments.ContainsKey(parameter.Name)) { - args = context.ActionArguments[parameter.Name]; + args = context.ActionArguments[ parameter.Name ]; } ValidateAttributes(parameter, args, context.ModelState); @@ -58,4 +58,4 @@ private void ValidateAttributes(ParameterInfo parameter, object args, ModelState } } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Controllers/AssetAdministrationShellRegistryAPIApi.cs b/src/IO.Swagger.Registry.Lib.V3/Controllers/AssetAdministrationShellRegistryAPIApi.cs index 4962db7c1..e76058ad3 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Controllers/AssetAdministrationShellRegistryAPIApi.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Controllers/AssetAdministrationShellRegistryAPIApi.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using AasxServer; using AasxServerStandardBib.Logging; using IO.Swagger.Lib.V3.Interfaces; @@ -27,7 +28,7 @@ namespace IO.Swagger.Controllers /// /// /// - [ApiController] + [ ApiController ] public class AssetAdministrationShellRegistryAPIApiController : ControllerBase { private readonly IAppLogger _logger; @@ -36,7 +37,8 @@ public class AssetAdministrationShellRegistryAPIApiController : ControllerBase private readonly IRegistryInitializerService _registryInitializerService; private readonly IAasDescriptorPaginationService _paginationService; - public AssetAdministrationShellRegistryAPIApiController(IAppLogger logger, IBase64UrlDecoderService decoderService, IAasRegistryService aasRegistryService, IRegistryInitializerService registryInitializerService, IAasDescriptorPaginationService paginationService) + public AssetAdministrationShellRegistryAPIApiController(IAppLogger logger, IBase64UrlDecoderService decoderService, + IAasRegistryService aasRegistryService, IRegistryInitializerService registryInitializerService, IAasDescriptorPaginationService paginationService) { _logger = logger; _decoderService = decoderService; @@ -44,6 +46,7 @@ public AssetAdministrationShellRegistryAPIApiController(IAppLogger /// Deletes an Asset Administration Shell Descriptor, i.e. de-registers an AAS /// @@ -53,15 +56,15 @@ public AssetAdministrationShellRegistryAPIApiController(IAppLoggerNot Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpDelete] - [Route("/shell-descriptors/{aasIdentifier}")] - [ValidateModelState] - [SwaggerOperation("DeleteAssetAdministrationShellDescriptorById")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult DeleteAssetAdministrationShellDescriptorById([FromRoute][Required] byte[] aasIdentifier) + [ HttpDelete ] + [ Route("/shell-descriptors/{aasIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("DeleteAssetAdministrationShellDescriptorById") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult DeleteAssetAdministrationShellDescriptorById([ FromRoute ] [ Required ] byte[] aasIdentifier) { //TODO: Uncomment the next line to return response 204 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(204); @@ -91,15 +94,16 @@ public virtual IActionResult DeleteAssetAdministrationShellDescriptorById([FromR /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpDelete] - [Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}")] - [ValidateModelState] - [SwaggerOperation("DeleteSubmodelDescriptorByIdThroughSuperpath")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult DeleteSubmodelDescriptorByIdThroughSuperpath([FromRoute][Required] string aasIdentifier, [FromRoute][Required] string submodelIdentifier) + [ HttpDelete ] + [ Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("DeleteSubmodelDescriptorByIdThroughSuperpath") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult DeleteSubmodelDescriptorByIdThroughSuperpath([ FromRoute ] [ Required ] string aasIdentifier, + [ FromRoute ] [ Required ] string submodelIdentifier) { //TODO: Uncomment the next line to return response 204 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(204); @@ -131,16 +135,17 @@ public virtual IActionResult DeleteSubmodelDescriptorByIdThroughSuperpath([FromR /// Forbidden /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/shell-descriptors")] - [ValidateModelState] - [SwaggerOperation("GetAllAssetAdministrationShellDescriptors")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Asset Administration Shell Descriptors")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllAssetAdministrationShellDescriptors([FromQuery] int? limit, [FromQuery] string cursor, [FromQuery] string assetKind, [FromQuery] string assetType) + [ HttpGet ] + [ Route("/shell-descriptors") ] + [ ValidateModelState ] + [ SwaggerOperation("GetAllAssetAdministrationShellDescriptors") ] + [ SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Asset Administration Shell Descriptors") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetAllAssetAdministrationShellDescriptors([ FromQuery ] int? limit, [ FromQuery ] string cursor, [ FromQuery ] string assetKind, + [ FromQuery ] string assetType) { // TODO (jtikekar, 2023-09-04): AssetType resembles AssetId from old Implementation List assetList = new List(); @@ -192,17 +197,18 @@ public virtual IActionResult GetAllAssetAdministrationShellDescriptors([FromQuer /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors")] - [ValidateModelState] - [SwaggerOperation("GetAllSubmodelDescriptorsThroughSuperpath")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Submodel Descriptors")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelDescriptorsThroughSuperpath([FromRoute][Required] string aasIdentifier, [FromQuery] int? limit, [FromQuery] string cursor) + [ HttpGet ] + [ Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors") ] + [ ValidateModelState ] + [ SwaggerOperation("GetAllSubmodelDescriptorsThroughSuperpath") ] + [ SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Submodel Descriptors") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetAllSubmodelDescriptorsThroughSuperpath([ FromRoute ] [ Required ] string aasIdentifier, [ FromQuery ] int? limit, + [ FromQuery ] string cursor) { //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(200, default(GetSubmodelDescriptorsResult)); @@ -237,17 +243,17 @@ public virtual IActionResult GetAllSubmodelDescriptorsThroughSuperpath([FromRout /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/shell-descriptors/{aasIdentifier}")] - [ValidateModelState] - [SwaggerOperation("GetAssetAdministrationShellDescriptorById")] - [SwaggerResponse(statusCode: 200, type: typeof(AssetAdministrationShellDescriptor), description: "Requested Asset Administration Shell Descriptor")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAssetAdministrationShellDescriptorById([FromRoute][Required] string aasIdentifier) + [ HttpGet ] + [ Route("/shell-descriptors/{aasIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("GetAssetAdministrationShellDescriptorById") ] + [ SwaggerResponse(statusCode: 200, type: typeof(AssetAdministrationShellDescriptor), description: "Requested Asset Administration Shell Descriptor") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetAssetAdministrationShellDescriptorById([ FromRoute ] [ Required ] string aasIdentifier) { var decodedAasIdentifier = _decoderService.Decode("aasIdentifier", aasIdentifier); _logger.LogInformation($"Received request to get the AAS Descriptor by Id"); @@ -273,7 +279,6 @@ public virtual IActionResult GetAssetAdministrationShellDescriptorById([FromRout } } } - } return NotFound(); @@ -290,17 +295,18 @@ public virtual IActionResult GetAssetAdministrationShellDescriptorById([FromRout /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpGet] - [Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}")] - [ValidateModelState] - [SwaggerOperation("GetSubmodelDescriptorByIdThroughSuperpath")] - [SwaggerResponse(statusCode: 200, type: typeof(SubmodelDescriptor), description: "Requested Submodel Descriptor")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelDescriptorByIdThroughSuperpath([FromRoute][Required] string aasIdentifier, [FromRoute][Required] string submodelIdentifier) + [ HttpGet ] + [ Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("GetSubmodelDescriptorByIdThroughSuperpath") ] + [ SwaggerResponse(statusCode: 200, type: typeof(SubmodelDescriptor), description: "Requested Submodel Descriptor") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult GetSubmodelDescriptorByIdThroughSuperpath([ FromRoute ] [ Required ] string aasIdentifier, + [ FromRoute ] [ Required ] string submodelIdentifier) { //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(200, default(SubmodelDescriptor)); @@ -333,17 +339,19 @@ public virtual IActionResult GetSubmodelDescriptorByIdThroughSuperpath([FromRout /// Internal Server Error /// Default error handling for unmentioned status codes //TODO (jtikekar, 2023-09-04): Routes are different than old impl - [HttpPost] - [Route("/shell-descriptors")] - [ValidateModelState] - [SwaggerOperation("PostAssetAdministrationShellDescriptor")] - [SwaggerResponse(statusCode: 201, type: typeof(AssetAdministrationShellDescriptor), description: "Asset Administration Shell Descriptor created successfully")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 409, type: typeof(Result), description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PostAssetAdministrationShellDescriptor([FromBody] AssetAdministrationShellDescriptor body) + [ HttpPost ] + [ Route("/shell-descriptors") ] + [ ValidateModelState ] + [ SwaggerOperation("PostAssetAdministrationShellDescriptor") ] + [ SwaggerResponse(statusCode: 201, type: typeof(AssetAdministrationShellDescriptor), description: "Asset Administration Shell Descriptor created successfully") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 409, type: typeof(Result), + description: + "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PostAssetAdministrationShellDescriptor([ FromBody ] AssetAdministrationShellDescriptor body) { var timestamp = DateTime.UtcNow; @@ -377,19 +385,20 @@ public virtual IActionResult PostAssetAdministrationShellDescriptor([FromBody] A /// Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request. /// Internal Server Error /// Default error handling for unmentioned status codes - - [HttpPost] - [Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors")] - [ValidateModelState] - [SwaggerOperation("PostSubmodelDescriptorThroughSuperpath")] - [SwaggerResponse(statusCode: 201, type: typeof(SubmodelDescriptor), description: "Submodel Descriptor created successfully")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 409, type: typeof(Result), description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PostSubmodelDescriptorThroughSuperpath([FromBody] SubmodelDescriptor body, [FromRoute][Required] string aasIdentifier) + [ HttpPost ] + [ Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors") ] + [ ValidateModelState ] + [ SwaggerOperation("PostSubmodelDescriptorThroughSuperpath") ] + [ SwaggerResponse(statusCode: 201, type: typeof(SubmodelDescriptor), description: "Submodel Descriptor created successfully") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 409, type: typeof(Result), + description: + "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PostSubmodelDescriptorThroughSuperpath([ FromBody ] SubmodelDescriptor body, [ FromRoute ] [ Required ] string aasIdentifier) { //TODO: Uncomment the next line to return response 201 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(201, default(SubmodelDescriptor)); @@ -425,16 +434,17 @@ public virtual IActionResult PostSubmodelDescriptorThroughSuperpath([FromBody] S /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpPut] - [Route("/shell-descriptors/{aasIdentifier}")] - [ValidateModelState] - [SwaggerOperation("PutAssetAdministrationShellDescriptorById")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PutAssetAdministrationShellDescriptorById([FromBody] AssetAdministrationShellDescriptor body, [FromRoute][Required] byte[] aasIdentifier) + [ HttpPut ] + [ Route("/shell-descriptors/{aasIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("PutAssetAdministrationShellDescriptorById") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PutAssetAdministrationShellDescriptorById([ FromBody ] AssetAdministrationShellDescriptor body, + [ FromRoute ] [ Required ] byte[] aasIdentifier) { //TODO: Uncomment the next line to return response 204 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(204); @@ -469,16 +479,17 @@ public virtual IActionResult PutAssetAdministrationShellDescriptorById([FromBody /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - [HttpPut] - [Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}")] - [ValidateModelState] - [SwaggerOperation("PutSubmodelDescriptorByIdThroughSuperpath")] - [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] - [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PutSubmodelDescriptorByIdThroughSuperpath([FromBody] SubmodelDescriptor body, [FromRoute][Required] string aasIdentifier, [FromRoute][Required] string submodelIdentifier) + [ HttpPut ] + [ Route("/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") ] + [ ValidateModelState ] + [ SwaggerOperation("PutSubmodelDescriptorByIdThroughSuperpath") ] + [ SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.") ] + [ SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden") ] + [ SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found") ] + [ SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error") ] + [ SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes") ] + public virtual IActionResult PutSubmodelDescriptorByIdThroughSuperpath([ FromBody ] SubmodelDescriptor body, [ FromRoute ] [ Required ] string aasIdentifier, + [ FromRoute ] [ Required ] string submodelIdentifier) { //TODO: Uncomment the next line to return response 204 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(204); @@ -501,12 +512,12 @@ public virtual IActionResult PutSubmodelDescriptorByIdThroughSuperpath([FromBody throw new NotImplementedException(); } - [HttpPost] - [Route("/overwrite-shell-descriptors")] - [ValidateModelState] - [SwaggerOperation("PostMultipleAssetAdministrationShellDescriptors")] - [SwaggerResponse(statusCode: 201, type: typeof(List), description: "Asset Administration Shell Descriptors created successfully")] - public virtual IActionResult PostMultipleAssetAdministrationShellDescriptor([FromBody] List body) + [ HttpPost ] + [ Route("/overwrite-shell-descriptors") ] + [ ValidateModelState ] + [ SwaggerOperation("PostMultipleAssetAdministrationShellDescriptors") ] + [ SwaggerResponse(statusCode: 201, type: typeof(List), description: "Asset Administration Shell Descriptors created successfully") ] + public virtual IActionResult PostMultipleAssetAdministrationShellDescriptor([ FromBody ] List body) { var timestamp = DateTime.UtcNow; @@ -515,7 +526,6 @@ public virtual IActionResult PostMultipleAssetAdministrationShellDescriptor([Fro _registryInitializerService.CreateMultipleAssetAdministrationShellDescriptor(body, timestamp); return new ObjectResult("ok"); - } /// @@ -524,14 +534,14 @@ public virtual IActionResult PostMultipleAssetAdministrationShellDescriptor([Fro /// The key-value-pair of an Asset identifier (BASE64-URL-encoded JSON-serialized key-value-pairs) /// An Asset identifier (BASE64-URL-encoded identifier) /// Requested Asset Administration Shell ids - [HttpGet] - [Route("/lookup/shells")] - [ValidateModelState] - [SwaggerOperation("GetAllAssetAdministrationShellIdsByAssetLink")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Asset Administration Shell ids")] + [ HttpGet ] + [ Route("/lookup/shells") ] + [ ValidateModelState ] + [ SwaggerOperation("GetAllAssetAdministrationShellIdsByAssetLink") ] + [ SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Asset Administration Shell ids") ] public virtual IActionResult GetAllAssetAdministrationShellIdsByAssetLink( - [FromQuery] List assetIds, - [FromQuery] string assetId) + [ FromQuery ] List assetIds, + [ FromQuery ] string assetId) { try { @@ -545,6 +555,7 @@ public virtual IActionResult GetAllAssetAdministrationShellIdsByAssetLink( assetList.Add(decodedAssetId); } } + // single assetId if (assetId != null && assetId != "") { @@ -587,4 +598,4 @@ public virtual IActionResult GetAllAssetAdministrationShellIdsByAssetLink( } } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Filters/BasePathFilter.cs b/src/IO.Swagger.Registry.Lib.V3/Filters/BasePathFilter.cs index 9c8584327..ae20b339a 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Filters/BasePathFilter.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Filters/BasePathFilter.cs @@ -32,7 +32,7 @@ public BasePathFilter(string basePath) /// FilterContext public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { - swaggerDoc.Servers.Add(new OpenApiServer() { Url = BasePath }); + swaggerDoc.Servers.Add(new OpenApiServer() {Url = BasePath}); var pathsToModify = swaggerDoc.Paths.Where(p => p.Key.StartsWith(BasePath)).ToList(); @@ -47,4 +47,4 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) } } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Filters/GeneratePathParamsValidationFilter.cs b/src/IO.Swagger.Registry.Lib.V3/Filters/GeneratePathParamsValidationFilter.cs index f7265130c..da3947270 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Filters/GeneratePathParamsValidationFilter.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Filters/GeneratePathParamsValidationFilter.cs @@ -24,7 +24,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) { var swaggerParam = operation.Parameters.SingleOrDefault(p => p.Name == par.Name); - var attributes = ((ControllerParameterDescriptor)par.ParameterDescriptor).ParameterInfo.CustomAttributes; + var attributes = ((ControllerParameterDescriptor) par.ParameterDescriptor).ParameterInfo.CustomAttributes; if (attributes != null && attributes.Count() > 0 && swaggerParam != null) { @@ -39,7 +39,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) var regexAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(RegularExpressionAttribute)); if (regexAttr != null) { - string regex = (string)regexAttr.ConstructorArguments[0].Value; + string regex = (string) regexAttr.ConstructorArguments[ 0 ].Value; if (swaggerParam is OpenApiParameter) { swaggerParam.Schema.Pattern = regex; @@ -53,21 +53,22 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (stringLengthAttr.NamedArguments.Count == 1) { - minLenght = (int)stringLengthAttr.NamedArguments.Single(p => p.MemberName == "MinimumLength").TypedValue.Value; + minLenght = (int) stringLengthAttr.NamedArguments.Single(p => p.MemberName == "MinimumLength").TypedValue.Value; } - maxLength = (int)stringLengthAttr.ConstructorArguments[0].Value; + + maxLength = (int) stringLengthAttr.ConstructorArguments[ 0 ].Value; } var minLengthAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(MinLengthAttribute)); if (minLengthAttr != null) { - minLenght = (int)minLengthAttr.ConstructorArguments[0].Value; + minLenght = (int) minLengthAttr.ConstructorArguments[ 0 ].Value; } var maxLengthAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(MaxLengthAttribute)); if (maxLengthAttr != null) { - maxLength = (int)maxLengthAttr.ConstructorArguments[0].Value; + maxLength = (int) maxLengthAttr.ConstructorArguments[ 0 ].Value; } if (swaggerParam is OpenApiParameter) @@ -80,8 +81,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) var rangeAttr = attributes.FirstOrDefault(p => p.AttributeType == typeof(RangeAttribute)); if (rangeAttr != null) { - int rangeMin = (int)rangeAttr.ConstructorArguments[0].Value; - int rangeMax = (int)rangeAttr.ConstructorArguments[1].Value; + int rangeMin = (int) rangeAttr.ConstructorArguments[ 0 ].Value; + int rangeMax = (int) rangeAttr.ConstructorArguments[ 1 ].Value; if (swaggerParam is OpenApiParameter) { @@ -93,4 +94,4 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) } } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorRequestFormatter.cs b/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorRequestFormatter.cs index cc1ee1ad4..df149e46d 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorRequestFormatter.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorRequestFormatter.cs @@ -53,6 +53,7 @@ public override Task ReadRequestBodyAsync(InputFormatterCo { aasDescList.Add(DescriptorDeserializer.AssetAdministrationShellDescriptorFrom(item)); } + result = aasDescList; } else @@ -63,4 +64,4 @@ public override Task ReadRequestBodyAsync(InputFormatterCo return InputFormatterResult.SuccessAsync(result); } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorResponseFormatter.cs b/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorResponseFormatter.cs index e41df4fac..f7d5799ca 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorResponseFormatter.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Formatters/AasDescriptorResponseFormatter.cs @@ -24,8 +24,8 @@ public static bool IsGenericListOfAasDesc(object o) { var oType = o.GetType(); return oType.IsGenericType && - (oType.GetGenericTypeDefinition() == typeof(List<>) && - (typeof(AssetAdministrationShellDescriptor).IsAssignableFrom(oType.GetGenericArguments()[0]))); + (oType.GetGenericTypeDefinition() == typeof(List<>) && + (typeof(AssetAdministrationShellDescriptor).IsAssignableFrom(oType.GetGenericArguments()[ 0 ]))); } public override bool CanWriteResult(OutputFormatterCanWriteContext context) @@ -71,27 +71,28 @@ public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) jsonArray.Add(json); } } + JsonObject jsonNode = new JsonObject(); - jsonNode["result"] = jsonArray; + jsonNode[ "result" ] = jsonArray; var pagingMetadata = new JsonObject(); if (cursor != null) { - pagingMetadata["cursor"] = cursor; + pagingMetadata[ "cursor" ] = cursor; } - jsonNode["paging_metadata"] = pagingMetadata; + + jsonNode[ "paging_metadata" ] = pagingMetadata; var writer = new Utf8JsonWriter(response.Body); jsonNode.WriteTo(writer); writer.FlushAsync().GetAwaiter().GetResult(); } else if (IsGenericListOfAasDesc(context.Object)) { - var jsonArray = new JsonArray(); - IList genericList = (IList)context.Object; + IList genericList = (IList) context.Object; List contextObjectType = new List(); foreach (var generic in genericList) { - contextObjectType.Add((AssetAdministrationShellDescriptor)generic); + contextObjectType.Add((AssetAdministrationShellDescriptor) generic); } foreach (var item in contextObjectType) @@ -99,6 +100,7 @@ public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) var json = DescriptorSerializer.ToJsonObject(item); jsonArray.Add(json); } + var writer = new Utf8JsonWriter(response.Body); jsonArray.WriteTo(writer); writer.FlushAsync().GetAwaiter().GetResult(); @@ -111,4 +113,4 @@ public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context) return Task.FromResult(response); } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/IO.Swagger.Registry.Lib.V3.csproj b/src/IO.Swagger.Registry.Lib.V3/IO.Swagger.Registry.Lib.V3.csproj index 2f9bf9317..b1f1e4f2e 100644 --- a/src/IO.Swagger.Registry.Lib.V3/IO.Swagger.Registry.Lib.V3.csproj +++ b/src/IO.Swagger.Registry.Lib.V3/IO.Swagger.Registry.Lib.V3.csproj @@ -1,32 +1,32 @@  - - IO.Swagger - IO.Swagger - net6.0 - true - true - IO.Swagger.Registry.Lib.V3 - IO.Swagger.Registry - Library - - - false - - - - - - - - - - - - - - - - - - - + + IO.Swagger + IO.Swagger + net6.0 + true + true + IO.Swagger.Registry.Lib.V3 + IO.Swagger.Registry + Library + + + false + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasDescriptorPaginationService.cs b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasDescriptorPaginationService.cs index cbbe05bc3..77993fe80 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasDescriptorPaginationService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasDescriptorPaginationService.cs @@ -9,4 +9,4 @@ public interface IAasDescriptorPaginationService { AasDescriptorPagedResult GetPaginatedList(List sourceList, PaginationParameters paginationParameters); } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasRegistryService.cs b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasRegistryService.cs index 96616f2ed..19b43504d 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasRegistryService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IAasRegistryService.cs @@ -9,4 +9,4 @@ public interface IAasRegistryService AssetAdministrationShellDescriptor CreateAasDescriptorFromDB(AasSet aasDB); List GetAllAssetAdministrationShellDescriptors(string assetKind = null, List assetList = null, string aasIdentifier = null); } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IRegistryInitializerService.cs b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IRegistryInitializerService.cs index 2a20fc567..6f8c95732 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Interfaces/IRegistryInitializerService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Interfaces/IRegistryInitializerService.cs @@ -15,4 +15,4 @@ public interface IRegistryInitializerService List GetRegistryList(); void InitRegistry(List cList, DateTime timestamp, bool initAgain = false); } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/AasDescriptorPagedResult.cs b/src/IO.Swagger.Registry.Lib.V3/Models/AasDescriptorPagedResult.cs index a8d9cfc56..73794ed19 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/AasDescriptorPagedResult.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/AasDescriptorPagedResult.cs @@ -9,4 +9,4 @@ public class AasDescriptorPagedResult public List result { get; set; } public PagedResultPagingMetadata paging_metadata { get; set; } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/AssetAdministrationShellDescriptor.cs b/src/IO.Swagger.Registry.Lib.V3/Models/AssetAdministrationShellDescriptor.cs index a58588a0e..d2f4e8c21 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/AssetAdministrationShellDescriptor.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/AssetAdministrationShellDescriptor.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -20,78 +21,80 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class AssetAdministrationShellDescriptor : Descriptor, IEquatable { /// /// Gets or Sets Administration /// - [DataMember(Name = "administration")] + [ DataMember(Name = "administration") ] public AdministrativeInformation Administration { get; set; } /// /// Gets or Sets AssetKind /// - [DataMember(Name = "assetKind")] + [ DataMember(Name = "assetKind") ] public AssetKind AssetKind { get; set; } /// /// Gets or Sets AssetType /// //[RegularExpression("/^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$/")] - [StringLength(2000, MinimumLength = 1)] - [DataMember(Name = "assetType")] + [ StringLength(2000, MinimumLength = 1) ] + [ DataMember(Name = "assetType") ] public string AssetType { get; set; } /// /// Gets or Sets Endpoints /// - [DataMember(Name = "endpoints")] + [ DataMember(Name = "endpoints") ] public List Endpoints { get; set; } /// /// Gets or Sets GlobalAssetId /// //[RegularExpression("/^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$/")] - [StringLength(2000, MinimumLength = 1)] - [DataMember(Name = "globalAssetId")] + [ StringLength(2000, MinimumLength = 1) ] + [ DataMember(Name = "globalAssetId") ] public string GlobalAssetId { get; set; } /// /// Gets or Sets IdShort /// - [MaxLength(128)] - [DataMember(Name = "idShort")] + [ MaxLength(128) ] + [ DataMember(Name = "idShort") ] public string IdShort { get; set; } /// /// Gets or Sets Id /// - [Required] + [ Required ] //[RegularExpression("/^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$/")] - [StringLength(2000, MinimumLength = 1)] - [DataMember(Name = "id")] + [ StringLength(2000, MinimumLength = 1) ] + [ DataMember(Name = "id") ] public string Id { get; set; } /// /// Gets or Sets SpecificAssetIds /// - [DataMember(Name = "specificAssetIds")] + [ DataMember(Name = "specificAssetIds") ] public List SpecificAssetIds { get; set; } /// /// Gets or Sets SubmodelDescriptors /// - [DataMember(Name = "submodelDescriptors")] + [ DataMember(Name = "submodelDescriptors") ] public List SubmodelDescriptors { get; set; } - public AssetAdministrationShellDescriptor(AdministrativeInformation administration = null, AssetKind assetKind = AssetKind.NotApplicable, string assetType = null, List endpoints = null, string globalAssetId = null, string idShort = null, string id = null, List specificAssetIds = null, List submodelDescriptors = null) + public AssetAdministrationShellDescriptor(AdministrativeInformation administration = null, AssetKind assetKind = AssetKind.NotApplicable, string assetType = null, + List endpoints = null, string globalAssetId = null, string idShort = null, string id = null, List specificAssetIds = null, + List submodelDescriptors = null) { Administration = administration; AssetKind = assetKind; @@ -143,7 +146,7 @@ public override bool Equals(object obj = null) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((AssetAdministrationShellDescriptor)obj); + return obj.GetType() == GetType() && Equals((AssetAdministrationShellDescriptor) obj); } /// @@ -237,6 +240,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(AssetAdministrationShellDescriptor left, AssetAdministrationShellDescriptor right) @@ -250,6 +254,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/Descriptor.cs b/src/IO.Swagger.Registry.Lib.V3/Models/Descriptor.cs index 84b1744c6..38150f087 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/Descriptor.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/Descriptor.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -19,28 +20,28 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class Descriptor : IEquatable { /// /// Gets or Sets Description /// - [DataMember(Name = "description")] + [ DataMember(Name = "description") ] public List Description { get; set; } /// /// Gets or Sets DisplayName /// - [DataMember(Name = "displayName")] + [ DataMember(Name = "displayName") ] public List DisplayName { get; set; } /// /// Gets or Sets Extensions /// - [DataMember(Name = "extensions")] + [ DataMember(Name = "extensions") ] public List Extensions { get; set; } /// @@ -76,7 +77,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Descriptor)obj); + return obj.GetType() == GetType() && Equals((Descriptor) obj); } /// @@ -128,6 +129,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(Descriptor left, Descriptor right) @@ -141,6 +143,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/Endpoint.cs b/src/IO.Swagger.Registry.Lib.V3/Models/Endpoint.cs index 2af328003..e9a4040f7 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/Endpoint.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/Endpoint.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.ComponentModel.DataAnnotations; @@ -18,24 +19,22 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class Endpoint : IEquatable { /// /// Gets or Sets _Interface /// - [Required] - - [MaxLength(128)] - [DataMember(Name = "interface")] + [ Required ] + [ MaxLength(128) ] + [ DataMember(Name = "interface") ] public string Interface { get; set; } /// /// Gets or Sets ProtocolInformation /// - [Required] - - [DataMember(Name = "protocolInformation")] + [ Required ] + [ DataMember(Name = "protocolInformation") ] public ProtocolInformation ProtocolInformation { get; set; } public Endpoint(string @interface = null, ProtocolInformation protocolInformation = null) @@ -76,7 +75,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Endpoint)obj); + return obj.GetType() == GetType() && Equals((Endpoint) obj); } /// @@ -121,6 +120,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(Endpoint left, Endpoint right) @@ -134,6 +134,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/Message.cs b/src/IO.Swagger.Registry.Lib.V3/Models/Message.cs index 0049f8c33..1fb57c199 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/Message.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/Message.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.ComponentModel.DataAnnotations; @@ -18,77 +19,76 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class Message : IEquatable { /// /// Gets or Sets Code /// - [StringLength(32, MinimumLength = 1)] - [DataMember(Name = "code")] + [ StringLength(32, MinimumLength = 1) ] + [ DataMember(Name = "code") ] public string Code { get; set; } /// /// Gets or Sets CorrelationId /// - [StringLength(128, MinimumLength = 1)] - [DataMember(Name = "correlationId")] + [ StringLength(128, MinimumLength = 1) ] + [ DataMember(Name = "correlationId") ] public string CorrelationId { get; set; } /// /// Gets or Sets MessageType /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [ JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter)) ] public enum MessageTypeEnum { /// /// Enum UndefinedEnum for Undefined /// - [EnumMember(Value = "Undefined")] - UndefinedEnum = 0, + [ EnumMember(Value = "Undefined") ] UndefinedEnum = 0, + /// /// Enum InfoEnum for Info /// - [EnumMember(Value = "Info")] - InfoEnum = 1, + [ EnumMember(Value = "Info") ] InfoEnum = 1, + /// /// Enum WarningEnum for Warning /// - [EnumMember(Value = "Warning")] - WarningEnum = 2, + [ EnumMember(Value = "Warning") ] WarningEnum = 2, + /// /// Enum ErrorEnum for Error /// - [EnumMember(Value = "Error")] - ErrorEnum = 3, + [ EnumMember(Value = "Error") ] ErrorEnum = 3, + /// /// Enum ExceptionEnum for Exception /// - [EnumMember(Value = "Exception")] - ExceptionEnum = 4 + [ EnumMember(Value = "Exception") ] ExceptionEnum = 4 } /// /// Gets or Sets MessageType /// - [DataMember(Name = "messageType")] + [ DataMember(Name = "messageType") ] public MessageTypeEnum? MessageType { get; set; } /// /// Gets or Sets Text /// - [DataMember(Name = "text")] + [ DataMember(Name = "text") ] public string Text { get; set; } /// /// Gets or Sets Timestamp /// //[RegularExpression("/^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|\\+00:00|-00:00)$/")] - [DataMember(Name = "timestamp")] + [ DataMember(Name = "timestamp") ] public string Timestamp { get; set; } /// @@ -126,7 +126,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Message)obj); + return obj.GetType() == GetType() && Equals((Message) obj); } /// @@ -192,6 +192,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(Message left, Message right) @@ -205,6 +206,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformation.cs b/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformation.cs index ad3d9045a..9591c1513 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformation.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformation.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -20,65 +21,65 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class ProtocolInformation : IEquatable { /// /// Gets or Sets Href /// - [Required] - - [MaxLength(2048)] - [DataMember(Name = "href")] + [ Required ] + [ MaxLength(2048) ] + [ DataMember(Name = "href") ] public string Href { get; set; } /// /// Gets or Sets EndpointProtocol /// - [MaxLength(128)] - [DataMember(Name = "endpointProtocol")] + [ MaxLength(128) ] + [ DataMember(Name = "endpointProtocol") ] public string EndpointProtocol { get; set; } /// /// Gets or Sets EndpointProtocolVersion /// - [DataMember(Name = "endpointProtocolVersion")] + [ DataMember(Name = "endpointProtocolVersion") ] public List EndpointProtocolVersion { get; set; } /// /// Gets or Sets Subprotocol /// - [MaxLength(128)] - [DataMember(Name = "subprotocol")] + [ MaxLength(128) ] + [ DataMember(Name = "subprotocol") ] public string Subprotocol { get; set; } /// /// Gets or Sets SubprotocolBody /// - [MaxLength(128)] - [DataMember(Name = "subprotocolBody")] + [ MaxLength(128) ] + [ DataMember(Name = "subprotocolBody") ] public string SubprotocolBody { get; set; } /// /// Gets or Sets SubprotocolBodyEncoding /// - [MaxLength(128)] - [DataMember(Name = "subprotocolBodyEncoding")] + [ MaxLength(128) ] + [ DataMember(Name = "subprotocolBodyEncoding") ] public string SubprotocolBodyEncoding { get; set; } /// /// Gets or Sets SecurityAttributes /// - [DataMember(Name = "securityAttributes")] + [ DataMember(Name = "securityAttributes") ] public List SecurityAttributes { get; set; } - public ProtocolInformation(string href = null, string endpointProtocol = null, List endpointProtocolVersion = null, string subprotocol = null, string subprotocolBody = null, string subprotocolBodyEncoding = null, List securityAttributes = null) + public ProtocolInformation(string href = null, string endpointProtocol = null, List endpointProtocolVersion = null, string subprotocol = null, + string subprotocolBody = null, string subprotocolBodyEncoding = null, List securityAttributes = null) { Href = href; EndpointProtocol = endpointProtocol; @@ -126,7 +127,7 @@ public override bool Equals(object obj = null) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((ProtocolInformation)obj); + return obj.GetType() == GetType() && Equals((ProtocolInformation) obj); } /// @@ -206,6 +207,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(ProtocolInformation left, ProtocolInformation right) @@ -219,6 +221,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformationSecurityAttributes.cs b/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformationSecurityAttributes.cs index 778276964..e11c2a22f 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformationSecurityAttributes.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/ProtocolInformationSecurityAttributes.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.ComponentModel.DataAnnotations; @@ -18,59 +19,57 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class ProtocolInformationSecurityAttributes : IEquatable { /// /// Gets or Sets Type /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [ JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter)) ] public enum TypeEnum { /// /// Enum NONEEnum for NONE /// - [EnumMember(Value = "NONE")] - NONEEnum = 0, + [ EnumMember(Value = "NONE") ] NONEEnum = 0, + /// /// Enum RFCTLSAEnum for RFC_TLSA /// - [EnumMember(Value = "RFC_TLSA")] - RFCTLSAEnum = 1, + [ EnumMember(Value = "RFC_TLSA") ] RFCTLSAEnum = 1, + /// /// Enum W3CDIDEnum for W3C_DID /// - [EnumMember(Value = "W3C_DID")] - W3CDIDEnum = 2 + [ EnumMember(Value = "W3C_DID") ] W3CDIDEnum = 2 } /// /// Gets or Sets Type /// - [Required] - - [DataMember(Name = "type")] + [ Required ] + [ DataMember(Name = "type") ] public TypeEnum? Type { get; set; } /// /// Gets or Sets Key /// - [Required] - - [DataMember(Name = "key")] + [ Required ] + [ DataMember(Name = "key") ] public string Key { get; set; } /// /// Gets or Sets Value /// - [Required] - - [DataMember(Name = "value")] + [ Required ] + [ DataMember(Name = "value") ] public string Value { get; set; } public ProtocolInformationSecurityAttributes(TypeEnum type, string key, string value) { - Type = type; Key = key; Value = value; + Type = type; + Key = key; + Value = value; } /// @@ -106,7 +105,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((ProtocolInformationSecurityAttributes)obj); + return obj.GetType() == GetType() && Equals((ProtocolInformationSecurityAttributes) obj); } /// @@ -158,6 +157,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(ProtocolInformationSecurityAttributes left, ProtocolInformationSecurityAttributes right) @@ -171,6 +171,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/Result.cs b/src/IO.Swagger.Registry.Lib.V3/Models/Result.cs index 024b83f51..521b3f477 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/Result.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/Result.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -19,14 +20,14 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class Result : IEquatable { /// /// Gets or Sets Messages /// - [DataMember(Name = "messages")] + [ DataMember(Name = "messages") ] public List Messages { get; set; } /// @@ -60,7 +61,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((Result)obj); + return obj.GetType() == GetType() && Equals((Result) obj); } /// @@ -74,10 +75,9 @@ public bool Equals(Result other) if (ReferenceEquals(this, other)) return true; return - - Messages == other.Messages || - Messages != null && - Messages.SequenceEqual(other.Messages) + Messages == other.Messages || + Messages != null && + Messages.SequenceEqual(other.Messages) ; } @@ -98,6 +98,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(Result left, Result right) @@ -111,6 +112,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Models/SubmodelDescriptor.cs b/src/IO.Swagger.Registry.Lib.V3/Models/SubmodelDescriptor.cs index cf4a0b1ac..91a123f1b 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Models/SubmodelDescriptor.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Models/SubmodelDescriptor.cs @@ -7,6 +7,7 @@ * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ + using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -20,53 +21,52 @@ namespace IO.Swagger.Registry.Lib.V3.Models /// /// /// - [DataContract] + [ DataContract ] public partial class SubmodelDescriptor : Descriptor, IEquatable { /// /// Gets or Sets Administration /// - [DataMember(Name = "administration")] + [ DataMember(Name = "administration") ] public AdministrativeInformation Administration { get; set; } /// /// Gets or Sets Endpoints /// - [Required] - - [DataMember(Name = "endpoints")] + [ Required ] + [ DataMember(Name = "endpoints") ] public List Endpoints { get; set; } /// /// Gets or Sets IdShort /// - [MaxLength(128)] - [DataMember(Name = "idShort")] + [ MaxLength(128) ] + [ DataMember(Name = "idShort") ] public string IdShort { get; set; } /// /// Gets or Sets Id /// - [Required] + [ Required ] //[RegularExpression("/^[\\x09\\x0A\\x0D\\x20-\\uD7FF\\uE000-\\uFFFD\\U00010000-\\U0010FFFF]*$/")] - [StringLength(2000, MinimumLength = 1)] - [DataMember(Name = "id")] + [ StringLength(2000, MinimumLength = 1) ] + [ DataMember(Name = "id") ] public string Id { get; set; } /// /// Gets or Sets SemanticId /// - [DataMember(Name = "semanticId")] + [ DataMember(Name = "semanticId") ] public Reference SemanticId { get; set; } /// /// Gets or Sets SupplementalSemanticId /// - [DataMember(Name = "supplementalSemanticId")] + [ DataMember(Name = "supplementalSemanticId") ] public List SupplementalSemanticId { get; set; } // TODO (jtikekar, 2023-09-04): @Andreas Not conformant with specifications @@ -74,10 +74,11 @@ public partial class SubmodelDescriptor : Descriptor, IEquatable - [DataMember(Name = "federatedElements")] + [ DataMember(Name = "federatedElements") ] public List FederatedElements { get; set; } - public SubmodelDescriptor(AdministrativeInformation administration = null, List endpoints = null, string idShort = null, string id = null, Reference semanticId = null, List supplementalSemanticId = null, List federatedElements = null) + public SubmodelDescriptor(AdministrativeInformation administration = null, List endpoints = null, string idShort = null, string id = null, + Reference semanticId = null, List supplementalSemanticId = null, List federatedElements = null) { Administration = administration; Endpoints = endpoints; @@ -124,7 +125,7 @@ public override bool Equals(object obj = null) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - return obj.GetType() == GetType() && Equals((SubmodelDescriptor)obj); + return obj.GetType() == GetType() && Equals((SubmodelDescriptor) obj); } /// @@ -197,6 +198,7 @@ public override int GetHashCode() } #region Operators + #pragma warning disable 1591 public static bool operator ==(SubmodelDescriptor left, SubmodelDescriptor right) @@ -210,6 +212,7 @@ public override int GetHashCode() } #pragma warning restore 1591 + #endregion Operators } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializeImplementation.cs b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializeImplementation.cs index a028e6e1f..4855b47c9 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializeImplementation.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializeImplementation.cs @@ -35,228 +35,248 @@ internal static AssetAdministrationShellDescriptor AssetAdministrationShellDescr { continue; } + switch (keyValue.Key) { case "administration": + { + if (keyValue.Value == null) { - if (keyValue.Value == null) - { - continue; - } - administrativeInformation = Jsonization.Deserialize.AdministrativeInformationFrom(keyValue.Value); - break; + continue; } + + administrativeInformation = Jsonization.Deserialize.AdministrativeInformationFrom(keyValue.Value); + break; + } case "assetKind": + { + if (keyValue.Value == null) { - if (keyValue.Value == null) - { - continue; - } - assetKind = Jsonization.Deserialize.AssetKindFrom(keyValue.Value); - break; + continue; } + + assetKind = Jsonization.Deserialize.AssetKindFrom(keyValue.Value); + break; + } case "assetType": + { + if (keyValue.Value == null) { - if (keyValue.Value == null) - { - continue; - } - assetType = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "id")); - return null; - } - break; + continue; + } + + assetType = StringFrom( + keyValue.Value, + out error); + if (error != null) + { + error.PrependSegment( + new Reporting.NameSegment( + "id")); + return null; } + + break; + } case "endpoints": + { + if (keyValue.Value == null) { - if (keyValue.Value == null) - { - continue; - } + continue; + } + + JsonArray? arrayEndpoints = keyValue.Value as JsonArray; + if (arrayEndpoints == null) + { + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "endpoints")); + return null; + } - JsonArray? arrayEndpoints = keyValue.Value as JsonArray; - if (arrayEndpoints == null) + endpoints = new List( + arrayEndpoints.Count); + int indexEndpoint = 0; + foreach (JsonNode? item in arrayEndpoints) + { + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpoint)); error.PrependSegment( new Reporting.NameSegment( "endpoints")); return null; } - endpoints = new List( - arrayEndpoints.Count); - int indexEndpoint = 0; - foreach (JsonNode? item in arrayEndpoints) - { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpoint)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoints")); - return null; - } - Endpoint? parsedItem = EndpointFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpoint)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoint")); - return null; - } - endpoints.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexEndpoint++; - } - break; - } - case "globalAssetId": - { - globalAssetId = StringFrom( - keyValue.Value, - out error); + + Endpoint? parsedItem = EndpointFrom( + item ?? throw new System.InvalidOperationException(), + out error); if (error != null) { + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpoint)); error.PrependSegment( new Reporting.NameSegment( - "globalAssetId")); + "endpoint")); return null; } - break; + + endpoints.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexEndpoint++; } + + break; + } + case "globalAssetId": + { + globalAssetId = StringFrom( + keyValue.Value, + out error); + if (error != null) + { + error.PrependSegment( + new Reporting.NameSegment( + "globalAssetId")); + return null; + } + + break; + } case "idShort": + { + idShort = StringFrom( + keyValue.Value, + out error); + if (error != null) { - idShort = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "idShort")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "idShort")); + return null; } + + break; + } case "id": + { + id = StringFrom( + keyValue.Value, + out error); + if (error != null) { - id = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "id")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "id")); + return null; } + + break; + } case "specificAssetIds": + { + JsonArray? arraySpecificAssetIds = keyValue.Value as JsonArray; + if (arraySpecificAssetIds == null) + { + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "specificAssetIds")); + return null; + } + + specificAssetIds = new List(arraySpecificAssetIds.Count); + int indexSpecificAssetId = 0; + foreach (JsonNode item in arraySpecificAssetIds) { - JsonArray? arraySpecificAssetIds = keyValue.Value as JsonArray; - if (arraySpecificAssetIds == null) + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexSpecificAssetId)); error.PrependSegment( new Reporting.NameSegment( - "specificAssetIds")); + "endpoints")); return null; } - specificAssetIds = new List(arraySpecificAssetIds.Count); - int indexSpecificAssetId = 0; - foreach (JsonNode item in arraySpecificAssetIds) - { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexSpecificAssetId)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoints")); - return null; - } - SpecificAssetId specificAssetId = Jsonization.Deserialize.SpecificAssetIdFrom(item); - specificAssetIds.Add(specificAssetId); - } - break; + + SpecificAssetId specificAssetId = Jsonization.Deserialize.SpecificAssetIdFrom(item); + specificAssetIds.Add(specificAssetId); } + + break; + } case "submodelDescriptors": + { + JsonArray? arraySubmodelDescriptors = keyValue.Value as JsonArray; + if (arraySubmodelDescriptors == null) + { + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "submodelDescriptors")); + return null; + } + + submodelDescriptors = new List( + arraySubmodelDescriptors.Count); + int indexSubmodelDescriptors = 0; + foreach (JsonNode? item in arraySubmodelDescriptors) { - JsonArray? arraySubmodelDescriptors = keyValue.Value as JsonArray; - if (arraySubmodelDescriptors == null) + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexSubmodelDescriptors)); error.PrependSegment( new Reporting.NameSegment( "submodelDescriptors")); return null; } - submodelDescriptors = new List( - arraySubmodelDescriptors.Count); - int indexSubmodelDescriptors = 0; - foreach (JsonNode? item in arraySubmodelDescriptors) + + SubmodelDescriptor? parsedItem = SubmodelDescriptorFrom( + item ?? throw new System.InvalidOperationException(), + out error); + if (error != null) { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexSubmodelDescriptors)); - error.PrependSegment( - new Reporting.NameSegment( - "submodelDescriptors")); - return null; - } - SubmodelDescriptor? parsedItem = SubmodelDescriptorFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexSubmodelDescriptors)); - error.PrependSegment( - new Reporting.NameSegment( - "submodelDescriptors")); - return null; - } - submodelDescriptors.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexSubmodelDescriptors++; + error.PrependSegment( + new Reporting.IndexSegment( + indexSubmodelDescriptors)); + error.PrependSegment( + new Reporting.NameSegment( + "submodelDescriptors")); + return null; } - break; + + submodelDescriptors.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexSubmodelDescriptors++; } + + break; + } } } - return new AssetAdministrationShellDescriptor(administrativeInformation, assetKind, assetType, endpoints, globalAssetId, idShort, id, specificAssetIds, submodelDescriptors); + return new AssetAdministrationShellDescriptor(administrativeInformation, assetKind, assetType, endpoints, globalAssetId, idShort, id, specificAssetIds, + submodelDescriptors); } internal static SubmodelDescriptor SubmodelDescriptorFrom(JsonNode node, out Reporting.Error error) @@ -285,184 +305,198 @@ internal static SubmodelDescriptor SubmodelDescriptorFrom(JsonNode node, out Rep { continue; } + switch (keyValue.Key) { case "administration": + { + administration = Jsonization.Deserialize.AdministrativeInformationFrom(keyValue.Value); + break; + } + case "endpoints": + { + if (keyValue.Value == null) { - administration = Jsonization.Deserialize.AdministrativeInformationFrom(keyValue.Value); - break; + continue; } - case "endpoints": + + JsonArray? arrayEndpoints = keyValue.Value as JsonArray; + if (arrayEndpoints == null) { - if (keyValue.Value == null) - { - continue; - } + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "endpoints")); + return null; + } - JsonArray? arrayEndpoints = keyValue.Value as JsonArray; - if (arrayEndpoints == null) + endpoints = new List( + arrayEndpoints.Count); + int indexEndpoint = 0; + foreach (JsonNode? item in arrayEndpoints) + { + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpoint)); error.PrependSegment( new Reporting.NameSegment( "endpoints")); return null; } - endpoints = new List( - arrayEndpoints.Count); - int indexEndpoint = 0; - foreach (JsonNode? item in arrayEndpoints) - { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpoint)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoints")); - return null; - } - Endpoint? parsedItem = EndpointFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpoint)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoint")); - return null; - } - endpoints.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexEndpoint++; - } - break; - } - case "idShort": - { - idShort = StringFrom( - keyValue.Value, - out error); + + Endpoint? parsedItem = EndpointFrom( + item ?? throw new System.InvalidOperationException(), + out error); if (error != null) { + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpoint)); error.PrependSegment( new Reporting.NameSegment( - "idShort")); + "endpoint")); return null; } - break; + + endpoints.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexEndpoint++; + } + + break; + } + case "idShort": + { + idShort = StringFrom( + keyValue.Value, + out error); + if (error != null) + { + error.PrependSegment( + new Reporting.NameSegment( + "idShort")); + return null; } + + break; + } case "id": + { + id = StringFrom( + keyValue.Value, + out error); + if (error != null) { - id = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "id")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "id")); + return null; } + + break; + } case "semanticId": + { + semanticId = Jsonization.Deserialize.ReferenceFrom(keyValue.Value); + break; + } + case "supplementalSemanticId": + { + JsonArray? arraySupplementalSemanticId = keyValue.Value as JsonArray; + if (arraySupplementalSemanticId == null) { - semanticId = Jsonization.Deserialize.ReferenceFrom(keyValue.Value); - break; + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "supplementalSemanticId")); + return null; } - case "supplementalSemanticId": + + supplementalSemanticId = new List(arraySupplementalSemanticId.Count); + int indexSpecificAssetId = 0; + foreach (JsonNode item in arraySupplementalSemanticId) { - JsonArray? arraySupplementalSemanticId = keyValue.Value as JsonArray; - if (arraySupplementalSemanticId == null) + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexSpecificAssetId)); error.PrependSegment( new Reporting.NameSegment( "supplementalSemanticId")); return null; } - supplementalSemanticId = new List(arraySupplementalSemanticId.Count); - int indexSpecificAssetId = 0; - foreach (JsonNode item in arraySupplementalSemanticId) - { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexSpecificAssetId)); - error.PrependSegment( - new Reporting.NameSegment( - "supplementalSemanticId")); - return null; - } - Reference suppSemanticId = Jsonization.Deserialize.ReferenceFrom(item); - supplementalSemanticId.Add(suppSemanticId); - } - break; + + Reference suppSemanticId = Jsonization.Deserialize.ReferenceFrom(item); + supplementalSemanticId.Add(suppSemanticId); } + + break; + } case "federatedElements": + { + JsonArray? arrayFederatedElements = keyValue.Value as JsonArray; + if (arrayFederatedElements == null) { - JsonArray? arrayFederatedElements = keyValue.Value as JsonArray; - if (arrayFederatedElements == null) + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "federatedElements")); + return null; + } + + federatedElements = new List( + arrayFederatedElements.Count); + int indexFederatedElements = 0; + foreach (JsonNode? item in arrayFederatedElements) + { + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexFederatedElements)); error.PrependSegment( new Reporting.NameSegment( "federatedElements")); return null; } - federatedElements = new List( - arrayFederatedElements.Count); - int indexFederatedElements = 0; - foreach (JsonNode? item in arrayFederatedElements) + + string? parsedItem = StringFrom( + item ?? throw new System.InvalidOperationException(), + out error); + if (error != null) { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexFederatedElements)); - error.PrependSegment( - new Reporting.NameSegment( - "federatedElements")); - return null; - } - string? parsedItem = StringFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexFederatedElements)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoint")); - return null; - } - federatedElements.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexFederatedElements++; + error.PrependSegment( + new Reporting.IndexSegment( + indexFederatedElements)); + error.PrependSegment( + new Reporting.NameSegment( + "endpoint")); + return null; } - break; + + federatedElements.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexFederatedElements++; } + + break; + } } } @@ -490,38 +524,40 @@ private static Endpoint EndpointFrom(JsonNode node, out Reporting.Error error) { continue; } + switch (keyValue.Key) { case "interface": + { + _interface = StringFrom( + keyValue.Value, + out error); + if (error != null) { - _interface = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "interface")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "interface")); + return null; } + + break; + } case "protocolInformation": + { + protocolInformation = ProtocolInformationFrom( + keyValue.Value, + out error); + if (error != null) { - protocolInformation = ProtocolInformationFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "protocolInformation")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "protocolInformation")); + return null; } - } + break; + } + } } return new Endpoint(_interface, protocolInformation); @@ -553,178 +589,192 @@ private static ProtocolInformation ProtocolInformationFrom(JsonNode node, out Re { continue; } + switch (keyValue.Key) { case "href": + { + href = StringFrom( + keyValue.Value, + out error); + if (error != null) { - href = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "href")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "href")); + return null; } + + break; + } case "endpointProtocol": + { + endpointProtocol = StringFrom( + keyValue.Value, + out error); + if (error != null) { - endpointProtocol = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "endpointProtocol")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "endpointProtocol")); + return null; } + + break; + } case "endpointProtocolVersion": + { + JsonArray? arrayEndpointsProtocolVersion = keyValue.Value as JsonArray; + if (arrayEndpointsProtocolVersion == null) + { + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "EndpointsProtocolVersion")); + return null; + } + + endpointProtocolVersion = new List( + arrayEndpointsProtocolVersion.Count); + int indexEndpointsProtocolVersion = 0; + foreach (JsonNode? item in arrayEndpointsProtocolVersion) { - JsonArray? arrayEndpointsProtocolVersion = keyValue.Value as JsonArray; - if (arrayEndpointsProtocolVersion == null) + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpointsProtocolVersion)); error.PrependSegment( new Reporting.NameSegment( "EndpointsProtocolVersion")); return null; } - endpointProtocolVersion = new List( - arrayEndpointsProtocolVersion.Count); - int indexEndpointsProtocolVersion = 0; - foreach (JsonNode? item in arrayEndpointsProtocolVersion) - { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpointsProtocolVersion)); - error.PrependSegment( - new Reporting.NameSegment( - "EndpointsProtocolVersion")); - return null; - } - string? parsedItem = StringFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexEndpointsProtocolVersion)); - error.PrependSegment( - new Reporting.NameSegment( - "endpoint")); - return null; - } - endpointProtocolVersion.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexEndpointsProtocolVersion++; - } - break; - } - case "subprotocol": - { - subprotocol = StringFrom( - keyValue.Value, - out error); + + string? parsedItem = StringFrom( + item ?? throw new System.InvalidOperationException(), + out error); if (error != null) { + error.PrependSegment( + new Reporting.IndexSegment( + indexEndpointsProtocolVersion)); error.PrependSegment( new Reporting.NameSegment( - "subprotocol")); + "endpoint")); return null; } - break; + + endpointProtocolVersion.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexEndpointsProtocolVersion++; + } + + break; + } + case "subprotocol": + { + subprotocol = StringFrom( + keyValue.Value, + out error); + if (error != null) + { + error.PrependSegment( + new Reporting.NameSegment( + "subprotocol")); + return null; } + + break; + } case "subprotocolBody": + { + subprotocolBody = StringFrom( + keyValue.Value, + out error); + if (error != null) { - subprotocolBody = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "subprotocolBody")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "subprotocolBody")); + return null; } + + break; + } case "subprotocolBodyEncoding": + { + subprotocolBodyEncoding = StringFrom( + keyValue.Value, + out error); + if (error != null) { - subprotocolBodyEncoding = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "subprotocolBodyEncoding")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "subprotocolBodyEncoding")); + return null; } + + break; + } case "securityAttributes": + { + JsonArray? arraySecurityAttributes = keyValue.Value as JsonArray; + if (arraySecurityAttributes == null) + { + error = new Reporting.Error( + $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + error.PrependSegment( + new Reporting.NameSegment( + "securityAttributes")); + return null; + } + + securityAttributes = new List( + arraySecurityAttributes.Count); + int indexSecurityAttributes = 0; + foreach (JsonNode? item in arraySecurityAttributes) { - JsonArray? arraySecurityAttributes = keyValue.Value as JsonArray; - if (arraySecurityAttributes == null) + if (item == null) { error = new Reporting.Error( - $"Expected a JsonArray, but got {keyValue.Value.GetType()}"); + "Expected a non-null item, but got a null"); + error.PrependSegment( + new Reporting.IndexSegment( + indexSecurityAttributes)); error.PrependSegment( new Reporting.NameSegment( - "securityAttributes")); + "SecurityAttributes")); return null; } - securityAttributes = new List( - arraySecurityAttributes.Count); - int indexSecurityAttributes = 0; - foreach (JsonNode? item in arraySecurityAttributes) + + ProtocolInformationSecurityAttributes? parsedItem = ProtocolInformationSecurityAttributesFrom( + item ?? throw new System.InvalidOperationException(), + out error); + if (error != null) { - if (item == null) - { - error = new Reporting.Error( - "Expected a non-null item, but got a null"); - error.PrependSegment( - new Reporting.IndexSegment( - indexSecurityAttributes)); - error.PrependSegment( - new Reporting.NameSegment( - "SecurityAttributes")); - return null; - } - ProtocolInformationSecurityAttributes? parsedItem = ProtocolInformationSecurityAttributesFrom( - item ?? throw new System.InvalidOperationException(), - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.IndexSegment( - indexSecurityAttributes)); - error.PrependSegment( - new Reporting.NameSegment( - "SecurityAttributes")); - return null; - } - securityAttributes.Add( - parsedItem - ?? throw new System.InvalidOperationException( - "Unexpected result null when error is null")); - indexSecurityAttributes++; + error.PrependSegment( + new Reporting.IndexSegment( + indexSecurityAttributes)); + error.PrependSegment( + new Reporting.NameSegment( + "SecurityAttributes")); + return null; } - break; + + securityAttributes.Add( + parsedItem + ?? throw new System.InvalidOperationException( + "Unexpected result null when error is null")); + indexSecurityAttributes++; } + + break; + } } } @@ -753,41 +803,44 @@ private static ProtocolInformationSecurityAttributes ProtocolInformationSecurity { continue; } + switch (keyValue.Key) { case "type": - { - //Enum.TryParse(typeof(ProtocolInformationSecurityAttributes.TypeEnum), out type); - break; - } + { + //Enum.TryParse(typeof(ProtocolInformationSecurityAttributes.TypeEnum), out type); + break; + } case "key": + { + key = StringFrom( + keyValue.Value, + out error); + if (error != null) { - key = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "key")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "key")); + return null; } + + break; + } case "value": + { + key = StringFrom( + keyValue.Value, + out error); + if (error != null) { - key = StringFrom( - keyValue.Value, - out error); - if (error != null) - { - error.PrependSegment( - new Reporting.NameSegment( - "value")); - return null; - } - break; + error.PrependSegment( + new Reporting.NameSegment( + "value")); + return null; } + + break; + } } } @@ -795,8 +848,8 @@ private static ProtocolInformationSecurityAttributes ProtocolInformationSecurity } internal static string? StringFrom( - JsonNode node, - out Reporting.Error? error) + JsonNode node, + out Reporting.Error? error) { error = null; JsonValue? value = node as JsonValue; @@ -806,6 +859,7 @@ private static ProtocolInformationSecurityAttributes ProtocolInformationSecurity $"Expected a JsonValue, but got {node.GetType()}"); return null; } + bool ok = value.TryGetValue(out string? result); if (!ok) { @@ -814,13 +868,15 @@ private static ProtocolInformationSecurityAttributes ProtocolInformationSecurity $"from {value.ToJsonString()}"); return null; } + if (result == null) { error = new Reporting.Error( "Expected a string, but got a null"); return null; } + return result; } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializer.cs b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializer.cs index 2a917b824..d02165862 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializer.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorDeserializer.cs @@ -8,33 +8,35 @@ public static class DescriptorDeserializer public static AssetAdministrationShellDescriptor AssetAdministrationShellDescriptorFrom(JsonNode node) { AssetAdministrationShellDescriptor? result = DescriptorDeserializeImplementation.AssetAdministrationShellDescriptorFrom( - node, - out Reporting.Error? error); + node, + out Reporting.Error? error); if (error != null) { throw new Jsonization.Exception( Reporting.GenerateJsonPath(error.PathSegments), error.Cause); } + return result - ?? throw new System.InvalidOperationException( - "Unexpected output null when error is null"); + ?? throw new System.InvalidOperationException( + "Unexpected output null when error is null"); } public static SubmodelDescriptor SubmodelDescriptorFrom(JsonNode node) { SubmodelDescriptor? result = DescriptorDeserializeImplementation.SubmodelDescriptorFrom( - node, - out Reporting.Error? error); + node, + out Reporting.Error? error); if (error != null) { throw new Jsonization.Exception( Reporting.GenerateJsonPath(error.PathSegments), error.Cause); } + return result - ?? throw new System.InvalidOperationException( - "Unexpected output null when error is null"); + ?? throw new System.InvalidOperationException( + "Unexpected output null when error is null"); } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorSerializer.cs b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorSerializer.cs index 45cb14507..aee6bfcc0 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorSerializer.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Serializers/DescriptorSerializer.cs @@ -22,7 +22,6 @@ public static JsonObject ToJsonObject(object that) { throw new NotSupportedException(); } - } private static JsonObject Transform(AssetAdministrationShellDescriptor that) @@ -33,17 +32,20 @@ private static JsonObject Transform(AssetAdministrationShellDescriptor that) var result = new JsonObject(); if (that.Administration != null) { - result["administration"] = Jsonization.Serialize.ToJsonObject(that.Administration); + result[ "administration" ] = Jsonization.Serialize.ToJsonObject(that.Administration); } + if (that.AssetKind != null) { - result["assetKind"] = Jsonization.Serialize.AssetKindToJsonValue( + result[ "assetKind" ] = Jsonization.Serialize.AssetKindToJsonValue( that.AssetKind); } + if (that.AssetType != null) { - result["assetType"] = that.AssetType; + result[ "assetType" ] = that.AssetType; } + if (that.Endpoints != null) { var arrayEndpoints = new JsonArray(); @@ -51,20 +53,25 @@ private static JsonObject Transform(AssetAdministrationShellDescriptor that) { arrayEndpoints.Add(Transform(endpoint)); } - result["endpoints"] = arrayEndpoints; + + result[ "endpoints" ] = arrayEndpoints; } + if (that.GlobalAssetId != null) { - result["globalAssetId"] = that.GlobalAssetId; + result[ "globalAssetId" ] = that.GlobalAssetId; } + if (that.IdShort != null) { - result["idShort"] = that.IdShort; + result[ "idShort" ] = that.IdShort; } + if (that.Id != null) { - result["id"] = that.Id; + result[ "id" ] = that.Id; } + if (that.SpecificAssetIds != null) { var arraySpecificAssetIds = new JsonArray(); @@ -72,8 +79,10 @@ private static JsonObject Transform(AssetAdministrationShellDescriptor that) { arraySpecificAssetIds.Add(Jsonization.Serialize.ToJsonObject(specificAssetId)); } - result["specificAssetIds"] = arraySpecificAssetIds; + + result[ "specificAssetIds" ] = arraySpecificAssetIds; } + if (that.SubmodelDescriptors != null) { var arraySubmodelDescriptors = new JsonArray(); @@ -81,7 +90,8 @@ private static JsonObject Transform(AssetAdministrationShellDescriptor that) { arraySubmodelDescriptors.Add(Transform(submodelDescriptor)); } - result["submodelDescriptors"] = arraySubmodelDescriptors; + + result[ "submodelDescriptors" ] = arraySubmodelDescriptors; } return result; @@ -95,7 +105,7 @@ private static JsonObject Transform(SubmodelDescriptor that) var result = new JsonObject(); if (that.Administration != null) { - result["administration"] = Jsonization.Serialize.ToJsonObject(that.Administration); + result[ "administration" ] = Jsonization.Serialize.ToJsonObject(that.Administration); } if (that.Endpoints != null) @@ -105,21 +115,25 @@ private static JsonObject Transform(SubmodelDescriptor that) { arrayEndpoints.Add(Transform(endpoint)); } - result["endpoints"] = arrayEndpoints; + + result[ "endpoints" ] = arrayEndpoints; } if (that.IdShort != null) { - result["idShort"] = that.IdShort; + result[ "idShort" ] = that.IdShort; } + if (that.Id != null) { - result["id"] = that.Id; + result[ "id" ] = that.Id; } + if (that.SemanticId != null) { - result["semanticId"] = Jsonization.Serialize.ToJsonObject(that.SemanticId); + result[ "semanticId" ] = Jsonization.Serialize.ToJsonObject(that.SemanticId); } + if (that.SupplementalSemanticId != null) { var arraySupplementalSemanticId = new JsonArray(); @@ -127,8 +141,10 @@ private static JsonObject Transform(SubmodelDescriptor that) { arraySupplementalSemanticId.Add(Jsonization.Serialize.ToJsonObject(suppSemId)); } - result["supplementalSemanticId"] = arraySupplementalSemanticId; + + result[ "supplementalSemanticId" ] = arraySupplementalSemanticId; } + if (that.FederatedElements != null) { var arrayFederatedElements = new JsonArray(); @@ -136,7 +152,8 @@ private static JsonObject Transform(SubmodelDescriptor that) { arrayFederatedElements.Add(fedElement); } - result["federatedElements"] = arrayFederatedElements; + + result[ "federatedElements" ] = arrayFederatedElements; } return result; @@ -151,12 +168,12 @@ private static JsonObject Transform(Endpoint that) if (that.Interface != null) { - result["interface"] = that.Interface; + result[ "interface" ] = that.Interface; } if (that.ProtocolInformation != null) { - result["protocolInformation"] = Transform(that.ProtocolInformation); + result[ "protocolInformation" ] = Transform(that.ProtocolInformation); } return result; @@ -171,12 +188,12 @@ private static JsonObject Transform(ProtocolInformation that) if (that.Href != null) { - result["href"] = that.Href; + result[ "href" ] = that.Href; } if (that.EndpointProtocol != null) { - result["endpointProtocol"] = that.EndpointProtocol; + result[ "endpointProtocol" ] = that.EndpointProtocol; } if (that.EndpointProtocolVersion != null) @@ -186,22 +203,23 @@ private static JsonObject Transform(ProtocolInformation that) { arrayProtocolVersion.Add(protocol); } - result["endpointProtocolVersion"] = arrayProtocolVersion; + + result[ "endpointProtocolVersion" ] = arrayProtocolVersion; } if (that.Subprotocol != null) { - result["subprotocol"] = that.Subprotocol; + result[ "subprotocol" ] = that.Subprotocol; } if (that.SubprotocolBody != null) { - result["subprotocolBody"] = that.SubprotocolBody; + result[ "subprotocolBody" ] = that.SubprotocolBody; } if (that.SubprotocolBodyEncoding != null) { - result["subprotocolBodyEncoding"] = that.SubprotocolBodyEncoding; + result[ "subprotocolBodyEncoding" ] = that.SubprotocolBodyEncoding; } if (that.SecurityAttributes != null) @@ -211,7 +229,8 @@ private static JsonObject Transform(ProtocolInformation that) { arraySecurityAttributes.Add(Transform(securityAttribute)); } - result["securityAttributes"] = arraySecurityAttributes; + + result[ "securityAttributes" ] = arraySecurityAttributes; } return result; @@ -225,18 +244,20 @@ private static JsonObject Transform(ProtocolInformationSecurityAttributes that) var result = new JsonObject(); if (that.Type != null) { - result["type"] = that.Type.ToString(); + result[ "type" ] = that.Type.ToString(); } + if (that.Key != null) { - result["key"] = that.Key; + result[ "key" ] = that.Key; } + if (that.Value != null) { - result["value"] = that.Value; + result[ "value" ] = that.Value; } return result; } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Services/AasDescriptorPaginationService.cs b/src/IO.Swagger.Registry.Lib.V3/Services/AasDescriptorPaginationService.cs index c310995bc..6c5f6e2ab 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Services/AasDescriptorPaginationService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Services/AasDescriptorPaginationService.cs @@ -57,10 +57,10 @@ private List GetPaginationList(List sourceList, int startIndex, int end for (int i = startIndex; i <= endIndex; i++) { - outputList.Add(sourceList[i]); + outputList.Add(sourceList[ i ]); } return outputList; } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Services/AasRegistryService.cs b/src/IO.Swagger.Registry.Lib.V3/Services/AasRegistryService.cs index 4cf03d2ad..0af2190ce 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Services/AasRegistryService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Services/AasRegistryService.cs @@ -49,7 +49,8 @@ public AssetAdministrationShellDescriptor CreateAasDescriptorFromDB(AasSet aasDB ad.GlobalAssetId = globalAssetId; // ad.SpecificAssetIds = new List(); - var specificAssetId = new SpecificAssetId("AssetKind", aasDB.AssetKind, externalSubjectId: new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, "assetKind") })); + var specificAssetId = new SpecificAssetId("AssetKind", aasDB.AssetKind, + externalSubjectId: new Reference(ReferenceTypes.ExternalReference, new List() {new Key(KeyTypes.GlobalReference, "assetKind")})); ad.SpecificAssetIds.Add(specificAssetId); // Submodels @@ -75,7 +76,7 @@ public AssetAdministrationShellDescriptor CreateAasDescriptorFromDB(AasSet aasDB { esm }; - sd.SemanticId = new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, submodelDB.SemanticId) }); + sd.SemanticId = new Reference(ReferenceTypes.ExternalReference, new List() {new Key(KeyTypes.GlobalReference, submodelDB.SemanticId)}); ad.SubmodelDescriptors.Add(sd); } } @@ -85,7 +86,8 @@ public AssetAdministrationShellDescriptor CreateAasDescriptorFromDB(AasSet aasDB } //getFromAasRegistry from old implementation - public List GetAllAssetAdministrationShellDescriptors(string assetKind = null, List assetList = null, string aasIdentifier = null) + public List GetAllAssetAdministrationShellDescriptors(string assetKind = null, List assetList = null, + string aasIdentifier = null) { List result = new List(); @@ -109,6 +111,7 @@ public List GetAllAssetAdministrationShellDe found = true; } } + if (found) result.Add(ad); } @@ -143,9 +146,9 @@ public List GetAllAssetAdministrationShellDe descriptorJSON = p.Value; break; } - } } + bool found = false; if (aasIdentifier == null && assetList.IsNullOrEmpty()) found = true; @@ -159,6 +162,7 @@ public List GetAllAssetAdministrationShellDe } } } + if (!assetList.IsNullOrEmpty()) { if (assetID != "" && descriptorJSON != "") @@ -169,6 +173,7 @@ public List GetAllAssetAdministrationShellDe } } } + if (found) { //ad = JsonConvert.DeserializeObject(descriptorJSON); @@ -181,12 +186,14 @@ public List GetAllAssetAdministrationShellDe { ad = null; } + result.Add(ad); } } } } + return result; } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/Services/RegistryInitializerService.cs b/src/IO.Swagger.Registry.Lib.V3/Services/RegistryInitializerService.cs index 307bd2794..9f6775150 100644 --- a/src/IO.Swagger.Registry.Lib.V3/Services/RegistryInitializerService.cs +++ b/src/IO.Swagger.Registry.Lib.V3/Services/RegistryInitializerService.cs @@ -6,8 +6,6 @@ using IO.Swagger.Registry.Lib.V3.Models; using IO.Swagger.Registry.Lib.V3.Serializers; using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; @@ -21,7 +19,6 @@ using System.Text; using System.Text.Json.Nodes; using System.Threading.Tasks; -using static AasxServer.Program; namespace IO.Swagger.Registry.Lib.V3.Services { @@ -42,10 +39,12 @@ public List GetRegistryList() { return getRegistry; } + public ISubmodel GetAasRegistry() { return aasRegistry; } + public List GetAasDescriptorsForSubmodelView() { return aasDescriptorsForSubmodelView; @@ -72,7 +71,7 @@ public void InitRegistry(List cList, DateTime timestamp, b int i = initiallyEmpty; while (i < AasxServer.Program.env.Length) { - AasxServer.Program.env[i] = null; + AasxServer.Program.env[ i ] = null; i++; } } @@ -83,7 +82,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; if (aas.IdShort == "REGISTRY") { envRegistry = env.AasEnv; @@ -100,6 +99,7 @@ public void InitRegistry(List cList, DateTime timestamp, b if (aasRegistry.SubmodelElements == null) aasRegistry.SubmodelElements = new List(); } + if (sm.IdShort == "SUBMODELREGISTRY") { submodelRegistry = sm; @@ -112,6 +112,7 @@ public void InitRegistry(List cList, DateTime timestamp, b } } } + if (aasRegistry != null) { getRegistry.Clear(); @@ -125,6 +126,7 @@ public void InitRegistry(List cList, DateTime timestamp, b Console.WriteLine("POST to Registry: " + registryURL); postRegistry.Add(registryURL); } + if (p.IdShort.ToLower() == "getregistry") { string registryURL = TranslateURL(p.Value); @@ -132,6 +134,7 @@ public void InitRegistry(List cList, DateTime timestamp, b getRegistry.Add(registryURL); } } + if (sme is SubmodelElementCollection smc) { if (smc.IdShort == "federatedElements") @@ -147,17 +150,19 @@ public void InitRegistry(List cList, DateTime timestamp, b } } } + foreach (AdminShellNS.AdminShellPackageEnv env in AasxServer.Program.env) { if (env != null) { if (env != null) { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; if (aas.IdShort != "REGISTRY" && aas.IdShort != "myAASwithGlobalSecurityMetaModel") { AddAasToRegistry(env, timestamp); } + if (aas.IdShort == "PcfViewTask") { string certificatePassword = "i40"; @@ -166,7 +171,10 @@ public void InitRegistry(List cList, DateTime timestamp, b { s2 = env.GetLocalStreamFromPackage("/aasx/files/Andreas_Orzelski_Chain.pfx", access: FileAccess.Read); } - catch { } + catch + { + } + if (s2 == null) { Console.WriteLine("Stream error!"); @@ -183,12 +191,12 @@ public void InitRegistry(List cList, DateTime timestamp, b Console.WriteLine("Client certificate: " + "/aasx/files/Andreas_Orzelski_Chain.pfx"); s2.Close(); } - } } } } } + if (getRegistry.Count != 0) { var submodelDescriptors = new List(); @@ -203,6 +211,16 @@ public void InitRegistry(List cList, DateTime timestamp, b // basyx with Submodel Registry: read submodel descriptors string requestPath = submodelRegistryUrl + "/submodel-descriptors"; + string queryPara = ""; + string userPW = ""; + string urlEdcWrapper = ""; + string replace = ""; + + if (AasxCredentials.get(cs.credentials, requestPath, out queryPara, out userPW, out urlEdcWrapper, out replace)) + { + if (replace != "") + requestPath = replace; + } var handler = new HttpClientHandler(); @@ -224,10 +242,7 @@ public void InitRegistry(List cList, DateTime timestamp, b try { Console.WriteLine("GET " + requestPath); - var task = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + var task = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task.Wait(); json = response.Content.ReadAsStringAsync().Result; // TODO (jtikekar, 2023-09-04): check this call flow @@ -240,7 +255,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { if (jo.ContainsKey("result")) { - node = (JsonNode)jo["result"]; + node = (JsonNode) jo[ "result" ]; if (node is JsonArray a) { foreach (JsonNode n in a) @@ -252,12 +267,14 @@ public void InitRegistry(List cList, DateTime timestamp, b } } } + error = !response.IsSuccessStatusCode; } catch { error = true; } + if (error) { string r = "ERROR GET; " + response.StatusCode.ToString(); @@ -267,7 +284,7 @@ public void InitRegistry(List cList, DateTime timestamp, b Console.WriteLine(r); } else // OK - { + { } } @@ -279,6 +296,16 @@ public void InitRegistry(List cList, DateTime timestamp, b string accessToken = null; //string requestPath = greg + "/" + "registry/shell-descriptors"; string requestPath = greg + "/shell-descriptors"; + string queryPara = ""; + string userPW = ""; + string urlEdcWrapper = ""; + string replace = ""; + + if (AasxCredentials.get(cs.credentials, requestPath, out queryPara, out userPW, out urlEdcWrapper, out replace)) + { + if (replace != "") + requestPath = replace; + } var handler = new HttpClientHandler(); @@ -291,7 +318,7 @@ public void InitRegistry(List cList, DateTime timestamp, b } var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(3); + client.Timeout = TimeSpan.FromSeconds(10); if (accessToken != null) client.SetBearerToken(accessToken); @@ -300,10 +327,7 @@ public void InitRegistry(List cList, DateTime timestamp, b try { Console.WriteLine("GET " + requestPath); - var task = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + var task = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task.Wait(); json = response.Content.ReadAsStringAsync().Result; // TODO (jtikekar, 2023-09-04): check this call flow @@ -316,7 +340,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { if (jo.ContainsKey("result")) { - node = (JsonNode)jo["result"]; + node = (JsonNode) jo[ "result" ]; if (node is JsonArray a) { foreach (JsonNode n in a) @@ -329,12 +353,9 @@ public void InitRegistry(List cList, DateTime timestamp, b ad.SubmodelDescriptors = new List(); if (ad.SubmodelDescriptors.Count == 0) { - requestPath = ad.Endpoints[0].ProtocolInformation.Href; + requestPath = ad.Endpoints[ 0 ].ProtocolInformation.Href; Console.WriteLine("GET " + requestPath); - task = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + task = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task.Wait(); json = response.Content.ReadAsStringAsync().Result; mStrm = new MemoryStream(Encoding.UTF8.GetBytes(json)); @@ -344,14 +365,16 @@ public void InitRegistry(List cList, DateTime timestamp, b var ids = new List(); foreach (var s in aas.Submodels) { - var id = s.Keys[0].Value; + var id = s.Keys[ 0 ].Value; ids.Add(id); } + foreach (var sd in submodelDescriptors) { if (ids.Contains(sd.Id)) ad.SubmodelDescriptors.Add(sd); } + aasDescriptorsForSubmodelView.Add(ad); } } @@ -360,12 +383,14 @@ public void InitRegistry(List cList, DateTime timestamp, b } } } + error = !response.IsSuccessStatusCode; } catch { error = true; } + if (error) { string r = "ERROR GET; " + response.StatusCode.ToString(); @@ -379,13 +404,15 @@ public void InitRegistry(List cList, DateTime timestamp, b int i = 0; while (i < AasxServer.Program.env.Length) { - var env = AasxServer.Program.env[i]; + var env = AasxServer.Program.env[ i ]; if (env == null) { break; } + i++; } + initiallyEmpty = i; foreach (var ad in aasDescriptors) { @@ -395,8 +422,9 @@ public void InitRegistry(List cList, DateTime timestamp, b var watch = System.Diagnostics.Stopwatch.StartNew(); // check, if AAS is exisiting and must be replaced - var extensions = new List { new Extension("endpoint", value: ad.Endpoints[0].ProtocolInformation.Href) }; - var aas = new AssetAdministrationShell(ad.Id, new AssetInformation(AssetKind.Instance, ad.GlobalAssetId), extensions, idShort: ad.IdShort + " - EXTERNAL"); + var extensions = new List {new Extension("endpoint", value: ad.Endpoints[ 0 ].ProtocolInformation.Href)}; + var aas = new AssetAdministrationShell(ad.Id, new AssetInformation(AssetKind.Instance, ad.GlobalAssetId), extensions, + idShort: ad.IdShort + " - EXTERNAL"); aas.TimeStamp = timestamp; aas.TimeStampCreate = timestamp; var newEnv = new AdminShellNS.AdminShellPackageEnv(); @@ -410,25 +438,29 @@ public void InitRegistry(List cList, DateTime timestamp, b bool success = false; bool external = false; string idEncoded = ""; - string endpoint = sd.Endpoints[0].ProtocolInformation.Href; + string endpoint = sd.Endpoints[ 0 ].ProtocolInformation.Href; var s1 = endpoint.Split("/shells/"); if (s1.Length == 2) { - var s2 = s1[1].Split("/submodels/"); + var s2 = s1[ 1 ].Split("/submodels/"); if (s2.Length == 2) { - idEncoded = s2[1].Replace("/submodel/", ""); ; - endpoint = s1[0] + "/submodels/" + idEncoded; + idEncoded = s2[ 1 ].Replace("/submodel/", ""); + ; + endpoint = s1[ 0 ] + "/submodels/" + idEncoded; } } + requestPath = endpoint; - string queryPara = ""; - string userPW = ""; - string urlEdcWrapper = ""; - string replace = ""; + queryPara = ""; + userPW = ""; + urlEdcWrapper = ""; + replace = ""; client.DefaultRequestHeaders.Clear(); if (AasxCredentials.get(cList, requestPath, out queryPara, out userPW, out urlEdcWrapper, out replace)) { + if (replace != "") + requestPath = replace; if (queryPara != "") queryPara = "?" + queryPara; if (userPW != "") @@ -479,13 +511,13 @@ public void InitRegistry(List cList, DateTime timestamp, b var now = DateTime.UtcNow; var claimList = new List() - { - new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), - new Claim(JwtClaimTypes.Subject, clientId), - new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), + { + new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()), + new Claim(JwtClaimTypes.Subject, clientId), + new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64), - new Claim("userName", userName), - }; + new Claim("userName", userName), + }; if (policy != "") claimList.Add(new Claim("policy", policy, ClaimValueTypes.String)); if (policyRequestedResource != "") @@ -497,7 +529,7 @@ public void InitRegistry(List cList, DateTime timestamp, b now, now.AddDays(1), credential) - ; + ; var tokenHandler = new JwtSecurityTokenHandler(); clientToken = tokenHandler.WriteToken(token); client.SetBearerToken(clientToken); @@ -505,10 +537,7 @@ public void InitRegistry(List cList, DateTime timestamp, b } Console.WriteLine("GET Submodel " + requestPath); - var task1 = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + var task1 = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task1.Wait(); if (response.IsSuccessStatusCode) { @@ -523,7 +552,7 @@ public void InitRegistry(List cList, DateTime timestamp, b sm.IdShort += " - COPY"; sm.Extensions = new List { - new Extension("endpoint", value: sd.Endpoints[0].ProtocolInformation.Href), + new Extension("endpoint", value: sd.Endpoints[ 0 ].ProtocolInformation.Href), new Extension("clientToken", value: clientToken) }; sm.SetAllParentsAndTimestamps(null, timestamp, timestamp); @@ -535,7 +564,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { Console.WriteLine("ERROR Deserialization " + requestPath + " " + ex.Message); - success= false; + success = false; } } } @@ -543,6 +572,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { success = false; } + break; default: // test if submodel is accessible @@ -559,12 +589,10 @@ public void InitRegistry(List cList, DateTime timestamp, b queryPara += "&level=core"; } } + requestPath += queryPara; Console.WriteLine("GET Submodel Core " + requestPath); - var task2 = Task.Run(async () => - { - response = await client.GetAsync(requestPath); - }); + var task2 = Task.Run(async () => { response = await client.GetAsync(requestPath); }); task2.Wait(); if (response.IsSuccessStatusCode) { @@ -576,6 +604,7 @@ public void InitRegistry(List cList, DateTime timestamp, b { success = false; } + break; } @@ -591,11 +620,12 @@ public void InitRegistry(List cList, DateTime timestamp, b if (external) sm.IdShort = sd.IdShort + " - EXTERNAL"; } + sm.Extensions = new List - { - new Extension("endpoint", value: sd.Endpoints[0].ProtocolInformation.Href), - new Extension("clientToken", value: clientToken) - }; + { + new Extension("endpoint", value: sd.Endpoints[ 0 ].ProtocolInformation.Href), + new Extension("clientToken", value: clientToken) + }; sm.SetAllParentsAndTimestamps(null, timestamp, timestamp); aas.AddSubmodelReference(sm.GetReference()); newEnv.AasEnv.Submodels.Add(sm); @@ -605,13 +635,14 @@ public void InitRegistry(List cList, DateTime timestamp, b watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds + " ms"); - AasxServer.Program.env[i] = newEnv; + AasxServer.Program.env[ i ] = newEnv; i++; } } } } } + AasxServer.Program.signalNewData(2); AasxServer.Program.initializingRegistry = false; @@ -645,7 +676,7 @@ static string TranslateURL(string url) static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime timestamp) #pragma warning restore IDE1006 // Benennungsstile { - var aas = env.AasEnv.AssetAdministrationShells[0]; + var aas = env.AasEnv.AssetAdministrationShells[ 0 ]; AssetAdministrationShellDescriptor ad = new AssetAdministrationShellDescriptor(); string globalAssetId = aas.AssetInformation.GlobalAssetId!; @@ -665,7 +696,7 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim ad.Endpoints.Add(e); ad.GlobalAssetId = globalAssetId; // - var extSubjId = new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, "assetKind") }); + var extSubjId = new Reference(ReferenceTypes.ExternalReference, new List() {new Key(KeyTypes.GlobalReference, "assetKind")}); var specificAssetId = new SpecificAssetId("assetKind", aas.AssetInformation.AssetKind.ToString(), externalSubjectId: extSubjId); ad.SpecificAssetIds = new List { @@ -699,69 +730,72 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim var sid = sm.SemanticId.GetAsExactlyOneKey(); if (sid != null) { - var semanticId = new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, sid.Value) }); + var semanticId = new Reference(ReferenceTypes.ExternalReference, new List() {new Key(KeyTypes.GlobalReference, sid.Value)}); sd.SemanticId = semanticId; } } + // add searchData for registry if (sm.SubmodelElements != null) - foreach (var se in sm.SubmodelElements) - { - var sme = se; - bool federate = false; - if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0 && sme.SemanticId.Keys[0] != null) + foreach (var se in sm.SubmodelElements) { - if (federatedElemensSemanticId.Contains(sme.SemanticId.Keys[0].Value)) - federate = true; - } - if (sme.Qualifiers != null && sme.Qualifiers.Count != 0) - { - if (sme.Qualifiers[0].Type == "federatedElement") - federate = true; - } + var sme = se; + bool federate = false; + if (sme.SemanticId != null && sme.SemanticId.Keys != null && sme.SemanticId.Keys.Count != 0 && sme.SemanticId.Keys[ 0 ] != null) + { + if (federatedElemensSemanticId.Contains(sme.SemanticId.Keys[ 0 ].Value)) + federate = true; + } - if (false && federate) - { - // TODO (jtikekar, 2023-09-04): @Andreas No Federated elements in sm Descriptor as per spec - if (sd.FederatedElements == null) - sd.FederatedElements = new List(); - string json = null; - // TODO (jtikekar, 2023-09-04): @Andreas why two serializations - //json = JsonConvert.SerializeObject(sme, Newtonsoft.Json.Formatting.Indented, - // new JsonSerializerSettings - // { - // NullValueHandling = NullValueHandling.Ignore - // }); - var j = Jsonization.Serialize.ToJsonObject(sme); - json = j.ToJsonString(); - /* - if (sme is Property p) + if (sme.Qualifiers != null && sme.Qualifiers.Count != 0) { - json = JsonConvert.SerializeObject(p, Newtonsoft.Json.Formatting.Indented, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }); + if (sme.Qualifiers[ 0 ].Type == "federatedElement") + federate = true; } - if (sme is SubmodelElementCollection sec) + + if (false && federate) { - json = JsonConvert.SerializeObject(sec, Newtonsoft.Json.Formatting.Indented, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }); + // TODO (jtikekar, 2023-09-04): @Andreas No Federated elements in sm Descriptor as per spec + if (sd.FederatedElements == null) + sd.FederatedElements = new List(); + string json = null; + // TODO (jtikekar, 2023-09-04): @Andreas why two serializations + //json = JsonConvert.SerializeObject(sme, Newtonsoft.Json.Formatting.Indented, + // new JsonSerializerSettings + // { + // NullValueHandling = NullValueHandling.Ignore + // }); + var j = Jsonization.Serialize.ToJsonObject(sme); + json = j.ToJsonString(); + /* + if (sme is Property p) + { + json = JsonConvert.SerializeObject(p, Newtonsoft.Json.Formatting.Indented, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }); + } + if (sme is SubmodelElementCollection sec) + { + json = JsonConvert.SerializeObject(sec, Newtonsoft.Json.Formatting.Indented, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }); + } + */ + /* + string tag = sme.idShort; + if (sme is AdminShell.Property p) + if (p.value != "") + tag += "=" + p.value; + */ + if (json != null) + sd.FederatedElements.Add(json); } - */ - /* - string tag = sme.idShort; - if (sme is AdminShell.Property p) - if (p.value != "") - tag += "=" + p.value; - */ - if (json != null) - sd.FederatedElements.Add(json); } - } + ad.SubmodelDescriptors.Add(sd); if (sm.IdShort.ToLower() == "nameplate") { @@ -784,15 +818,17 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim var sid = sm.SemanticId.GetAsExactlyOneKey(); if (sid != null) { - var semanticId = new Reference(ReferenceTypes.ExternalReference, new List() { new Key(KeyTypes.GlobalReference, sid.Value) }); + var semanticId = new Reference(ReferenceTypes.ExternalReference, new List() {new Key(KeyTypes.GlobalReference, sid.Value)}); sd.SemanticId = semanticId; } } + ad.SubmodelDescriptors.Add(sd); } } } } + // add to internal registry if (postRegistry.Contains("this")) AddAasDescriptorToRegistry(ad, timestamp, true); @@ -812,7 +848,6 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim { if (pr == "this") { - continue; } @@ -824,6 +859,7 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim //requestPath = requestPath + "/registry/shell-descriptors"; requestPath = requestPath + "/shell-descriptors"; } + //string json = JsonConvert.SerializeObject(ad); string json = DescriptorSerializer.ToJsonObject(ad).ToJsonString(); @@ -859,6 +895,7 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim { error = true; } + if (error) { string r = "ERROR POST; " + response.StatusCode.ToString(); @@ -868,6 +905,7 @@ static void AddAasToRegistry(AdminShellNS.AdminShellPackageEnv env, DateTime tim Console.WriteLine(r); } } + watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds + " ms"); } @@ -886,8 +924,9 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da string endpoint = ""; if (ad.Endpoints != null && ad.Endpoints.Count != 0) { - endpoint = ad.Endpoints[0].ProtocolInformation.Href; + endpoint = ad.Endpoints[ 0 ].ProtocolInformation.Href; } + // overwrite existing entry, if assetID AND aasID are identical if (!initial) { @@ -912,6 +951,7 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da pep = ep; } } + if (found == 2 && pjson != null) { //string s = JsonConvert.SerializeObject(ad); @@ -956,12 +996,14 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da { p.Value = assetID; } + c.Value.Add(p); p = new Property(DataTypeDefXsd.String, idShort: "endpoint"); p.TimeStampCreate = timestamp; p.TimeStamp = timestamp; p.Value = endpoint; - c.Value.Add(p); p = new Property(DataTypeDefXsd.String, idShort: "descriptorJSON"); + c.Value.Add(p); + p = new Property(DataTypeDefXsd.String, idShort: "descriptorJSON"); p.TimeStampCreate = timestamp; p.TimeStamp = timestamp; p.Value = DescriptorSerializer.ToJsonObject(ad).ToJsonString(); @@ -1004,8 +1046,9 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da cs.Value.Add(ps); if (sd.Endpoints != null && sd.Endpoints.Count != 0) { - endpoint = sd.Endpoints[0].ProtocolInformation.Href; + endpoint = sd.Endpoints[ 0 ].ProtocolInformation.Href; } + ps = new Property(DataTypeDefXsd.String, idShort: "endpoint"); ps.TimeStampCreate = timestamp; ps.TimeStamp = timestamp; @@ -1039,19 +1082,20 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da int last = r.Value.Keys.Count - 1; while (first < last) { - var temp = r.Value.Keys[first]; - r.Value.Keys[first] = r.Value.Keys[last]; - r.Value.Keys[last] = temp; + var temp = r.Value.Keys[ first ]; + r.Value.Keys[ first ] = r.Value.Keys[ last ]; + r.Value.Keys[ last ] = temp; first++; last--; } + c.Value.Add(r); if (sd.IdShort == "NameplateVC") { if (sd.Endpoints != null && sd.Endpoints.Count > 0) { - var ep = sd.Endpoints[0].ProtocolInformation.Href; + var ep = sd.Endpoints[ 0 ].ProtocolInformation.Href; p = new Property(DataTypeDefXsd.String, idShort: "NameplateVC"); p.TimeStampCreate = timestamp; p.TimeStamp = timestamp; @@ -1059,6 +1103,7 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da cs.Value.Add(p); } } + // TODO (jtikekar, 2023-09-04): @Andreas if (sd.FederatedElements != null && sd.FederatedElements.Count != 0) { @@ -1081,7 +1126,9 @@ static void AddAasDescriptorToRegistry(AssetAdministrationShellDescriptor ad, Da // p.value = fe; smc.Value.Add(sme); } - catch { } + catch + { + } } } } @@ -1110,4 +1157,4 @@ public void CreateMultipleAssetAdministrationShellDescriptor(List - { - endpoints.MapControllers(); - }); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); if (env.IsDevelopment()) { @@ -137,4 +132,4 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF } } } -} +} \ No newline at end of file diff --git a/src/IO.Swagger.Registry.Lib.V3/wwwroot/web.config b/src/IO.Swagger.Registry.Lib.V3/wwwroot/web.config index e70a7778d..495a86853 100644 --- a/src/IO.Swagger.Registry.Lib.V3/wwwroot/web.config +++ b/src/IO.Swagger.Registry.Lib.V3/wwwroot/web.config @@ -1,9 +1,10 @@ + - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/es6numberserializer/NumberCachedPowers.cs b/src/es6numberserializer/NumberCachedPowers.cs index e34a6439b..f21985ee1 100644 --- a/src/es6numberserializer/NumberCachedPowers.cs +++ b/src/es6numberserializer/NumberCachedPowers.cs @@ -41,7 +41,7 @@ namespace Org.Webpki.Es6NumberSerialization { class NumberCachedPowers { - const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) + const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) class CachedPower { @@ -51,7 +51,7 @@ class CachedPower internal CachedPower(ulong significand, short binaryExponent, short decimalExponent) { - this.significand = (long)significand; + this.significand = (long) significand; this.binaryExponent = binaryExponent; this.decimalExponent = decimalExponent; } @@ -61,8 +61,8 @@ public static int GetCachedPower(int e, int alpha, int gamma, NumberDiyFp c_mk) { int kQ = NumberDiyFp.kSignificandSize; double k = Math.Ceiling((alpha - e + kQ - 1) * kD_1_LOG2_10); - int index = (GRISU_CACHE_OFFSET + (int)k - 1) / CACHED_POWERS_SPACING + 1; - CachedPower cachedPower = CACHED_POWERS[index]; + int index = (GRISU_CACHE_OFFSET + (int) k - 1) / CACHED_POWERS_SPACING + 1; + CachedPower cachedPower = CACHED_POWERS[ index ]; c_mk.SetF(cachedPower.significand); c_mk.SetE(cachedPower.binaryExponent); @@ -79,88 +79,88 @@ public static int GetCachedPower(int e, int alpha, int gamma, NumberDiyFp c_mk) static readonly CachedPower[] CACHED_POWERS = { - new CachedPower(0xe61acf033d1a45dfL, -1087, -308), - new CachedPower(0xab70fe17c79ac6caL, -1060, -300), - new CachedPower(0xff77b1fcbebcdc4fL, -1034, -292), - new CachedPower(0xbe5691ef416bd60cL, -1007, -284), - new CachedPower(0x8dd01fad907ffc3cL, -980, -276), - new CachedPower(0xd3515c2831559a83L, -954, -268), - new CachedPower(0x9d71ac8fada6c9b5L, -927, -260), - new CachedPower(0xea9c227723ee8bcbL, -901, -252), - new CachedPower(0xaecc49914078536dL, -874, -244), - new CachedPower(0x823c12795db6ce57L, -847, -236), - new CachedPower(0xc21094364dfb5637L, -821, -228), - new CachedPower(0x9096ea6f3848984fL, -794, -220), - new CachedPower(0xd77485cb25823ac7L, -768, -212), - new CachedPower(0xa086cfcd97bf97f4L, -741, -204), - new CachedPower(0xef340a98172aace5L, -715, -196), - new CachedPower(0xb23867fb2a35b28eL, -688, -188), - new CachedPower(0x84c8d4dfd2c63f3bL, -661, -180), - new CachedPower(0xc5dd44271ad3cdbaL, -635, -172), - new CachedPower(0x936b9fcebb25c996L, -608, -164), - new CachedPower(0xdbac6c247d62a584L, -582, -156), - new CachedPower(0xa3ab66580d5fdaf6L, -555, -148), - new CachedPower(0xf3e2f893dec3f126L, -529, -140), - new CachedPower(0xb5b5ada8aaff80b8L, -502, -132), - new CachedPower(0x87625f056c7c4a8bL, -475, -124), - new CachedPower(0xc9bcff6034c13053L, -449, -116), - new CachedPower(0x964e858c91ba2655L, -422, -108), - new CachedPower(0xdff9772470297ebdL, -396, -100), - new CachedPower(0xa6dfbd9fb8e5b88fL, -369, -92), - new CachedPower(0xf8a95fcf88747d94L, -343, -84), - new CachedPower(0xb94470938fa89bcfL, -316, -76), - new CachedPower(0x8a08f0f8bf0f156bL, -289, -68), - new CachedPower(0xcdb02555653131b6L, -263, -60), - new CachedPower(0x993fe2c6d07b7facL, -236, -52), - new CachedPower(0xe45c10c42a2b3b06L, -210, -44), - new CachedPower(0xaa242499697392d3L, -183, -36), - new CachedPower(0xfd87b5f28300ca0eL, -157, -28), - new CachedPower(0xbce5086492111aebL, -130, -20), - new CachedPower(0x8cbccc096f5088ccL, -103, -12), - new CachedPower(0xd1b71758e219652cL, -77, -4), - new CachedPower(0x9c40000000000000L, -50, 4), - new CachedPower(0xe8d4a51000000000L, -24, 12), - new CachedPower(0xad78ebc5ac620000L, 3, 20), - new CachedPower(0x813f3978f8940984L, 30, 28), - new CachedPower(0xc097ce7bc90715b3L, 56, 36), - new CachedPower(0x8f7e32ce7bea5c70L, 83, 44), - new CachedPower(0xd5d238a4abe98068L, 109, 52), - new CachedPower(0x9f4f2726179a2245L, 136, 60), - new CachedPower(0xed63a231d4c4fb27L, 162, 68), - new CachedPower(0xb0de65388cc8ada8L, 189, 76), - new CachedPower(0x83c7088e1aab65dbL, 216, 84), - new CachedPower(0xc45d1df942711d9aL, 242, 92), - new CachedPower(0x924d692ca61be758L, 269, 100), - new CachedPower(0xda01ee641a708deaL, 295, 108), - new CachedPower(0xa26da3999aef774aL, 322, 116), - new CachedPower(0xf209787bb47d6b85L, 348, 124), - new CachedPower(0xb454e4a179dd1877L, 375, 132), - new CachedPower(0x865b86925b9bc5c2L, 402, 140), - new CachedPower(0xc83553c5c8965d3dL, 428, 148), - new CachedPower(0x952ab45cfa97a0b3L, 455, 156), - new CachedPower(0xde469fbd99a05fe3L, 481, 164), - new CachedPower(0xa59bc234db398c25L, 508, 172), - new CachedPower(0xf6c69a72a3989f5cL, 534, 180), - new CachedPower(0xb7dcbf5354e9beceL, 561, 188), - new CachedPower(0x88fcf317f22241e2L, 588, 196), - new CachedPower(0xcc20ce9bd35c78a5L, 614, 204), - new CachedPower(0x98165af37b2153dfL, 641, 212), - new CachedPower(0xe2a0b5dc971f303aL, 667, 220), - new CachedPower(0xa8d9d1535ce3b396L, 694, 228), - new CachedPower(0xfb9b7cd9a4a7443cL, 720, 236), - new CachedPower(0xbb764c4ca7a44410L, 747, 244), - new CachedPower(0x8bab8eefb6409c1aL, 774, 252), - new CachedPower(0xd01fef10a657842cL, 800, 260), - new CachedPower(0x9b10a4e5e9913129L, 827, 268), - new CachedPower(0xe7109bfba19c0c9dL, 853, 276), - new CachedPower(0xac2820d9623bf429L, 880, 284), - new CachedPower(0x80444b5e7aa7cf85L, 907, 292), - new CachedPower(0xbf21e44003acdd2dL, 933, 300), - new CachedPower(0x8e679c2f5e44ff8fL, 960, 308), - new CachedPower(0xd433179d9c8cb841L, 986, 316), - new CachedPower(0x9e19db92b4e31ba9L, 1013, 324), - new CachedPower(0xeb96bf6ebadf77d9L, 1039, 332), - new CachedPower(0xaf87023b9bf0ee6bL, 1066, 340) + new CachedPower(0xe61acf033d1a45dfL, -1087, -308), + new CachedPower(0xab70fe17c79ac6caL, -1060, -300), + new CachedPower(0xff77b1fcbebcdc4fL, -1034, -292), + new CachedPower(0xbe5691ef416bd60cL, -1007, -284), + new CachedPower(0x8dd01fad907ffc3cL, -980, -276), + new CachedPower(0xd3515c2831559a83L, -954, -268), + new CachedPower(0x9d71ac8fada6c9b5L, -927, -260), + new CachedPower(0xea9c227723ee8bcbL, -901, -252), + new CachedPower(0xaecc49914078536dL, -874, -244), + new CachedPower(0x823c12795db6ce57L, -847, -236), + new CachedPower(0xc21094364dfb5637L, -821, -228), + new CachedPower(0x9096ea6f3848984fL, -794, -220), + new CachedPower(0xd77485cb25823ac7L, -768, -212), + new CachedPower(0xa086cfcd97bf97f4L, -741, -204), + new CachedPower(0xef340a98172aace5L, -715, -196), + new CachedPower(0xb23867fb2a35b28eL, -688, -188), + new CachedPower(0x84c8d4dfd2c63f3bL, -661, -180), + new CachedPower(0xc5dd44271ad3cdbaL, -635, -172), + new CachedPower(0x936b9fcebb25c996L, -608, -164), + new CachedPower(0xdbac6c247d62a584L, -582, -156), + new CachedPower(0xa3ab66580d5fdaf6L, -555, -148), + new CachedPower(0xf3e2f893dec3f126L, -529, -140), + new CachedPower(0xb5b5ada8aaff80b8L, -502, -132), + new CachedPower(0x87625f056c7c4a8bL, -475, -124), + new CachedPower(0xc9bcff6034c13053L, -449, -116), + new CachedPower(0x964e858c91ba2655L, -422, -108), + new CachedPower(0xdff9772470297ebdL, -396, -100), + new CachedPower(0xa6dfbd9fb8e5b88fL, -369, -92), + new CachedPower(0xf8a95fcf88747d94L, -343, -84), + new CachedPower(0xb94470938fa89bcfL, -316, -76), + new CachedPower(0x8a08f0f8bf0f156bL, -289, -68), + new CachedPower(0xcdb02555653131b6L, -263, -60), + new CachedPower(0x993fe2c6d07b7facL, -236, -52), + new CachedPower(0xe45c10c42a2b3b06L, -210, -44), + new CachedPower(0xaa242499697392d3L, -183, -36), + new CachedPower(0xfd87b5f28300ca0eL, -157, -28), + new CachedPower(0xbce5086492111aebL, -130, -20), + new CachedPower(0x8cbccc096f5088ccL, -103, -12), + new CachedPower(0xd1b71758e219652cL, -77, -4), + new CachedPower(0x9c40000000000000L, -50, 4), + new CachedPower(0xe8d4a51000000000L, -24, 12), + new CachedPower(0xad78ebc5ac620000L, 3, 20), + new CachedPower(0x813f3978f8940984L, 30, 28), + new CachedPower(0xc097ce7bc90715b3L, 56, 36), + new CachedPower(0x8f7e32ce7bea5c70L, 83, 44), + new CachedPower(0xd5d238a4abe98068L, 109, 52), + new CachedPower(0x9f4f2726179a2245L, 136, 60), + new CachedPower(0xed63a231d4c4fb27L, 162, 68), + new CachedPower(0xb0de65388cc8ada8L, 189, 76), + new CachedPower(0x83c7088e1aab65dbL, 216, 84), + new CachedPower(0xc45d1df942711d9aL, 242, 92), + new CachedPower(0x924d692ca61be758L, 269, 100), + new CachedPower(0xda01ee641a708deaL, 295, 108), + new CachedPower(0xa26da3999aef774aL, 322, 116), + new CachedPower(0xf209787bb47d6b85L, 348, 124), + new CachedPower(0xb454e4a179dd1877L, 375, 132), + new CachedPower(0x865b86925b9bc5c2L, 402, 140), + new CachedPower(0xc83553c5c8965d3dL, 428, 148), + new CachedPower(0x952ab45cfa97a0b3L, 455, 156), + new CachedPower(0xde469fbd99a05fe3L, 481, 164), + new CachedPower(0xa59bc234db398c25L, 508, 172), + new CachedPower(0xf6c69a72a3989f5cL, 534, 180), + new CachedPower(0xb7dcbf5354e9beceL, 561, 188), + new CachedPower(0x88fcf317f22241e2L, 588, 196), + new CachedPower(0xcc20ce9bd35c78a5L, 614, 204), + new CachedPower(0x98165af37b2153dfL, 641, 212), + new CachedPower(0xe2a0b5dc971f303aL, 667, 220), + new CachedPower(0xa8d9d1535ce3b396L, 694, 228), + new CachedPower(0xfb9b7cd9a4a7443cL, 720, 236), + new CachedPower(0xbb764c4ca7a44410L, 747, 244), + new CachedPower(0x8bab8eefb6409c1aL, 774, 252), + new CachedPower(0xd01fef10a657842cL, 800, 260), + new CachedPower(0x9b10a4e5e9913129L, 827, 268), + new CachedPower(0xe7109bfba19c0c9dL, 853, 276), + new CachedPower(0xac2820d9623bf429L, 880, 284), + new CachedPower(0x80444b5e7aa7cf85L, 907, 292), + new CachedPower(0xbf21e44003acdd2dL, 933, 300), + new CachedPower(0x8e679c2f5e44ff8fL, 960, 308), + new CachedPower(0xd433179d9c8cb841L, 986, 316), + new CachedPower(0x9e19db92b4e31ba9L, 1013, 324), + new CachedPower(0xeb96bf6ebadf77d9L, 1039, 332), + new CachedPower(0xaf87023b9bf0ee6bL, 1066, 340) }; const int GRISU_CACHE_MAX_DISTANCE = 27; @@ -168,4 +168,4 @@ public static int GetCachedPower(int e, int alpha, int gamma, NumberDiyFp c_mk) const int GRISU_CACHE_OFFSET = 308; } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberDToA.cs b/src/es6numberserializer/NumberDToA.cs index 1dd95d6cd..92faf7773 100644 --- a/src/es6numberserializer/NumberDToA.cs +++ b/src/es6numberserializer/NumberDToA.cs @@ -34,13 +34,12 @@ namespace Org.Webpki.Es6NumberSerialization { class NumberDToA { - public const int - DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */ - DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */ - DTOSTR_FIXED = 2, /* Round to digits after the decimal point; exponential if number is large */ - DTOSTR_EXPONENTIAL = 3, /* Always exponential format; significant digits */ - DTOSTR_PRECISION = 4; /* Either fixed or exponential format; significant digits */ + DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */ + DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */ + DTOSTR_FIXED = 2, /* Round to digits after the decimal point; exponential if number is large */ + DTOSTR_EXPONENTIAL = 3, /* Always exponential format; significant digits */ + DTOSTR_PRECISION = 4; /* Either fixed or exponential format; significant digits */ private const int Frac_mask = 0xfffff; @@ -77,11 +76,11 @@ public const int 1e20, 1e21, 1e22 }; - private static double[] bigtens = { 1e16, 1e32, 1e64, 1e128, 1e256 }; + private static double[] bigtens = {1e16, 1e32, 1e64, 1e128, 1e256}; private static int Lo0bits(int inty) { - uint y = (uint)inty; + uint y = (uint) inty; uint k; uint x = y; @@ -93,29 +92,35 @@ private static int Lo0bits(int inty) { return 1; } + return 2; } + k = 0; if ((x & 0xffff) == 0) { k = 16; x >>= 16; } + if ((x & 0xff) == 0) { k += 8; x >>= 8; } + if ((x & 0xf) == 0) { k += 4; x >>= 4; } + if ((x & 0x3) == 0) { k += 2; x >>= 2; } + if ((x & 1) == 0) { k++; @@ -123,7 +128,8 @@ private static int Lo0bits(int inty) if ((x & 1) == 0) return 32; } - return (int)k; + + return (int) k; } /* Return the number (0 through 32) of most significant zero bits in x. */ @@ -136,36 +142,41 @@ private static int Hi0bits(int x) k = 16; x <<= 16; } + if ((x & 0xff000000) == 0) { k += 8; x <<= 8; } + if ((x & 0xf0000000) == 0) { k += 4; x <<= 4; } + if ((x & 0xc0000000) == 0) { k += 2; x <<= 2; } + if ((x & 0x80000000) == 0) { k++; if ((x & 0x40000000) == 0) return 32; } + return k; } private static void StuffBits(byte[] bits, int offset, int val) { - bits[offset] = (byte)(val >> 24); - bits[offset + 1] = (byte)(val >> 16); - bits[offset + 2] = (byte)(val >> 8); - bits[offset + 3] = (byte)(val); + bits[ offset ] = (byte) (val >> 24); + bits[ offset + 1 ] = (byte) (val >> 16); + bits[ offset + 2 ] = (byte) (val >> 8); + bits[ offset + 3 ] = (byte) (val); } /* Convert d into the form b*2^e, where b is an odd integer. b is the returned @@ -175,12 +186,12 @@ private static BigInteger D2B(double d, int[] e, int[] bits) { byte[] dbl_bits; int i, k, y, z, de; - ulong dBits = (ulong)BitConverter.DoubleToInt64Bits(d); - int d0 = (int)(dBits >> 32); - int d1 = (int)(dBits); + ulong dBits = (ulong) BitConverter.DoubleToInt64Bits(d); + int d0 = (int) (dBits >> 32); + int d1 = (int) (dBits); z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ if ((de = (d0 >> Exp_shift)) != 0) z |= Exp_msk1; @@ -189,7 +200,7 @@ private static BigInteger D2B(double d, int[] e, int[] bits) { dbl_bits = new byte[8]; k = Lo0bits(y); - y = (int)((uint)y >> k); + y = (int) ((uint) y >> k); if (k != 0) { StuffBits(dbl_bits, 4, y | z << (32 - k)); @@ -197,6 +208,7 @@ private static BigInteger D2B(double d, int[] e, int[] bits) } else StuffBits(dbl_bits, 4, y); + StuffBits(dbl_bits, 0, z); i = (z != 0) ? 2 : 1; } @@ -211,22 +223,25 @@ private static BigInteger D2B(double d, int[] e, int[] bits) k += 32; i = 1; } + if (de != 0) { - e[0] = de - Bias - (P - 1) + k; - bits[0] = P - k; + e[ 0 ] = de - Bias - (P - 1) + k; + bits[ 0 ] = P - k; } else { - e[0] = de - Bias - (P - 1) + 1 + k; - bits[0] = 32 * i - Hi0bits(z); + e[ 0 ] = de - Bias - (P - 1) + 1 + k; + bits[ 0 ] = 32 * i - Hi0bits(z); } + byte[] reverse = new byte[dbl_bits.Length]; int q = dbl_bits.Length; foreach (byte b in dbl_bits) { - reverse[--q] = b; + reverse[ --q ] = b; } + return new BigInteger(reverse); } @@ -267,20 +282,20 @@ private static BigInteger D2B(double d, int[] e, int[] bits) static int Word0(double d) { long dBits = BitConverter.DoubleToInt64Bits(d); - return (int)(dBits >> 32); + return (int) (dBits >> 32); } private static double SetWord0(double d, int i) { long dBits = BitConverter.DoubleToInt64Bits(d); - dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL); + dBits = ((long) i << 32) | (dBits & 0x0FFFFFFFFL); return BitConverter.Int64BitsToDouble(dBits); } private static int Word1(double d) { long dBits = BitConverter.DoubleToInt64Bits(d); - return (int)(dBits); + return (int) (dBits); } /* Return b * 5^k. k must be nonnegative. */ @@ -296,14 +311,15 @@ private static bool RoundOff(StringBuilder buf) while (i != 0) { --i; - char c = buf[i]; + char c = buf[ i ]; if (c != '9') { - buf[i] = (char)(c + 1); + buf[ i ] = (char) (c + 1); buf.Length = i + 1; return false; } } + buf.Length = 0; return true; } @@ -316,7 +332,7 @@ private static bool RoundOff(StringBuilder buf) /* bufsize should be at least 20 for modes 0 and 1. For the other modes, * bufsize should be two greater than the maximum number of output characters expected. */ public static int JS_dtoa(double d, int mode, bool biasUp, int ndigits, - bool[] sign, StringBuilder buf) + bool[] sign, StringBuilder buf) { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from @@ -352,8 +368,21 @@ Values of mode other than 0-9 are treated as mode 0. to hold the suppressed trailing zeros. */ - int b2, b5, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, m2, m5, s2, s5; + int b2, + b5, + i, + ieps, + ilim, + ilim0, + ilim1, + j, + j1, + k, + k0, + m2, + m5, + s2, + s5; char dig; long L; long x; @@ -366,12 +395,12 @@ to hold the suppressed trailing zeros. if ((Word0(d) & Sign_bit) != 0) { /* set sign for everything, including 0's and NaNs */ - sign[0] = true; + sign[ 0 ] = true; // Word0(d) &= ~Sign_bit; /* clear sign bit */ d = SetWord0(d, Word0(d) & ~Sign_bit); } else - sign[0] = false; + sign[ 0 ] = false; if ((Word0(d) & Exp_mask) == Exp_mask) { @@ -379,16 +408,17 @@ to hold the suppressed trailing zeros. buf.Append(((Word1(d) == 0) && ((Word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN"); return 9999; } + if (d == 0) { // no_digits: buf.Length = 0; - buf.Append('0'); /* copy "0" to buffer */ + buf.Append('0'); /* copy "0" to buffer */ return 1; } b = D2B(d, be, bbits); - if ((i = ((int)(((uint)Word0(d)) >> Exp_shift1) & (Exp_mask >> Exp_shift1))) != 0) + if ((i = ((int) (((uint) Word0(d)) >> Exp_shift1) & (Exp_mask >> Exp_shift1))) != 0) { d2 = SetWord0(d, (Word0(d) & Frac_mask1) | Exp_11); /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 @@ -418,31 +448,33 @@ to hold the suppressed trailing zeros. else { /* d is denormalized */ - i = bbits[0] + be[0] + (Bias + (P - 1) - 1); + i = bbits[ 0 ] + be[ 0 ] + (Bias + (P - 1) - 1); x = (i > 32) - ? ((long)Word0(d)) << (64 - i) | (((uint)Word1(d)) >> (i - 32)) - : ((long)Word1(d)) << (32 - i); + ? ((long) Word0(d)) << (64 - i) | (((uint) Word1(d)) >> (i - 32)) + : ((long) Word1(d)) << (32 - i); // d2 = x; // Word0(d2) -= 31*Exp_msk1; /* adjust exponent */ d2 = SetWord0(x, Word0(x) - 31 * Exp_msk1); i -= (Bias + (P - 1) - 1) + 1; denorm = true; } + /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ ds = (d2 - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981; - k = (int)ds; + k = (int) ds; if (ds < 0.0 && ds != k) - k--; /* want k = floor(ds) */ + k--; /* want k = floor(ds) */ k_check = true; if (k >= 0 && k <= Ten_pmax) { - if (d < tens[k]) + if (d < tens[ k ]) k--; k_check = false; } + /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. If k_check is zero, we're guaranteed that k = floor(log10(d)). */ - j = bbits[0] - i - 1; + j = bbits[ 0 ] - i - 1; /* At this point d = b/2^j, where b is an odd integer. */ if (j >= 0) { @@ -454,6 +486,7 @@ to hold the suppressed trailing zeros. b2 = -j; s2 = 0; } + if (k >= 0) { b5 = 0; @@ -466,6 +499,7 @@ to hold the suppressed trailing zeros. b5 = -k; s5 = 0; } + /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ if (mode < 0 || mode > 9) @@ -476,6 +510,7 @@ to hold the suppressed trailing zeros. mode -= 4; try_quick = false; } + leftright = true; ilim = ilim1 = 0; switch (mode) @@ -514,7 +549,6 @@ when it turns out that k was computed too high by one. */ bool fast_failed = false; if (ilim >= 0 && ilim <= Quick_max && try_quick) { - /* Try to get by with floating-point arithmetic. */ i = 0; @@ -525,33 +559,36 @@ when it turns out that k was computed too high by one. */ /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ if (k > 0) { - ds = tens[k & 0xf]; + ds = tens[ k & 0xf ]; j = k >> 4; if ((j & Bletch) != 0) { /* prevent overflows */ j &= Bletch - 1; - d /= bigtens[n_bigtens - 1]; + d /= bigtens[ n_bigtens - 1 ]; ieps++; } + for (; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; - ds *= bigtens[i]; + ds *= bigtens[ i ]; } + d /= ds; } else if ((j1 = -k) != 0) { - d *= tens[j1 & 0xf]; + d *= tens[ j1 & 0xf ]; for (j = j1 >> 4; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; - d *= bigtens[i]; + d *= bigtens[ i ]; } } + /* Check that k was computed correctly. */ if (k_check && d < 1.0 && ilim > 0) { @@ -565,6 +602,7 @@ when it turns out that k was computed too high by one. */ ieps++; } } + /* eps bounds the cumulative error. */ // eps = ieps*d + 7.0; // Word0(eps) -= (P-1)*Exp_msk1; @@ -580,14 +618,17 @@ when it turns out that k was computed too high by one. */ k++; return k + 1; } + if (d < -eps) { buf.Length = 0; - buf.Append('0'); /* copy "0" to buffer */ + buf.Append('0'); /* copy "0" to buffer */ return 1; } + fast_failed = true; } + if (!fast_failed) { fast_failed = true; @@ -596,23 +637,24 @@ when it turns out that k was computed too high by one. */ /* Use Steele & White method of only * generating digits needed. */ - eps = 0.5 / tens[ilim - 1] - eps; - for (i = 0; ;) + eps = 0.5 / tens[ ilim - 1 ] - eps; + for (i = 0;;) { - L = (long)d; + L = (long) d; d -= L; - buf.Append((char)('0' + L)); + buf.Append((char) ('0' + L)); if (d < eps) { return k + 1; } + if (1.0 - d < eps) { // goto bump_up; char lastCh; while (true) { - lastCh = buf[buf.Length - 1]; + lastCh = buf[ buf.Length - 1 ]; buf.Length = buf.Length - 1; if (lastCh != '9') break; if (buf.Length == 0) @@ -622,9 +664,11 @@ when it turns out that k was computed too high by one. */ break; } } - buf.Append((char)(lastCh + 1)); + + buf.Append((char) (lastCh + 1)); return k + 1; } + if (++i >= ilim) break; eps *= 10.0; @@ -634,12 +678,12 @@ when it turns out that k was computed too high by one. */ else { /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim - 1]; - for (i = 1; ; i++, d *= 10.0) + eps *= tens[ ilim - 1 ]; + for (i = 1;; i++, d *= 10.0) { - L = (long)d; + L = (long) d; d -= L; - buf.Append((char)('0' + L)); + buf.Append((char) ('0' + L)); if (i == ilim) { if (d > 0.5 + eps) @@ -648,7 +692,7 @@ when it turns out that k was computed too high by one. */ char lastCh; while (true) { - lastCh = buf[buf.Length - 1]; + lastCh = buf[ buf.Length - 1 ]; buf.Length = buf.Length - 1; if (lastCh != '9') break; if (buf.Length == 0) @@ -658,7 +702,8 @@ when it turns out that k was computed too high by one. */ break; } } - buf.Append((char)(lastCh + 1)); + + buf.Append((char) (lastCh + 1)); return k + 1; } else if (d < 0.5 - eps) @@ -668,11 +713,13 @@ when it turns out that k was computed too high by one. */ // s++; return k + 1; } + break; } } } } + if (fast_failed) { buf.Length = 0; @@ -684,27 +731,29 @@ when it turns out that k was computed too high by one. */ /* Do we have a "small" integer? */ - if (be[0] >= 0 && k <= Int_max) + if (be[ 0 ] >= 0 && k <= Int_max) { /* Yes. */ - ds = tens[k]; + ds = tens[ k ]; if (ndigits < 0 && ilim <= 0) { if (ilim < 0 || d < 5 * ds || (!biasUp && d == 5 * ds)) { buf.Length = 0; - buf.Append('0'); /* copy "0" to buffer */ + buf.Append('0'); /* copy "0" to buffer */ return 1; } + buf.Append('1'); k++; return k + 1; } - for (i = 1; ; i++) + + for (i = 1;; i++) { - L = (long)(d / ds); + L = (long) (d / ds); d -= L * ds; - buf.Append((char)('0' + L)); + buf.Append((char) ('0' + L)); if (i == ilim) { d += d; @@ -721,7 +770,7 @@ when it turns out that k was computed too high by one. */ char lastCh; while (true) { - lastCh = buf[buf.Length - 1]; + lastCh = buf[ buf.Length - 1 ]; buf.Length = buf.Length - 1; if (lastCh != '9') break; if (buf.Length == 0) @@ -731,14 +780,18 @@ when it turns out that k was computed too high by one. */ break; } } - buf.Append((char)(lastCh + 1)); + + buf.Append((char) (lastCh + 1)); } + break; } + d *= 10.0; if (d == 0) break; } + return k + 1; } @@ -749,7 +802,7 @@ when it turns out that k was computed too high by one. */ { if (mode < 2) { - i = (denorm) ? be[0] + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits[0]; + i = (denorm) ? be[ 0 ] + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits[ 0 ]; /* i is 1 plus the number of trailing zero bits in d's significand. Thus, (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ } @@ -764,6 +817,7 @@ when it turns out that k was computed too high by one. */ b5 += j; m5 = 0; } + if ((i = ilim) < 0) { m2 -= i; @@ -771,12 +825,14 @@ when it turns out that k was computed too high by one. */ } /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ } + b2 += i; s2 += i; mhi = 1; /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or input (when mode < 2) significant digit, divided by 10^k. */ } + /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in b2, m2, and s2 without changing the equalities. */ if (m2 > 0 && s2 > 0) @@ -798,6 +854,7 @@ when it turns out that k was computed too high by one. */ b1 = mhi * b; b = b1; } + if ((j = b5 - m5) != 0) b = Pow5mult(b, j); } @@ -818,8 +875,8 @@ when it turns out that k was computed too high by one. */ if (mode < 2) { if ((Word1(d) == 0) && ((Word0(d) & Bndry_mask) == 0) - && ((Word0(d) & (Exp_mask & Exp_mask << 1)) != 0) - ) + && ((Word0(d) & (Exp_mask & Exp_mask << 1)) != 0) + ) { /* The special case. Here we want to be within a quarter of the last input significant digit instead of one half of it when the decimal output string's value is less than d. */ @@ -837,14 +894,15 @@ significant digit instead of one half of it when the decimal output string's val * can do shifts and ors to compute the numerator for q. */ byte[] S_bytes = S.ToByteArray(); - Array.Reverse(S_bytes); // Note: Opposite to java + Array.Reverse(S_bytes); // Note: Opposite to java int S_hiWord = 0; for (int idx = 0; idx < 4; idx++) { S_hiWord = (S_hiWord << 8); if (idx < S_bytes.Length) - S_hiWord |= (S_bytes[idx] & 0xFF); + S_hiWord |= (S_bytes[ idx ] & 0xFF); } + if ((i = (((s5 != 0) ? 32 - Hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0) i = 32 - i; /* i is the number of leading zero bits in the most significant word of S*2^s2. */ @@ -862,6 +920,7 @@ significant digit instead of one half of it when the decimal output string's val m2 += i; s2 += i; } + /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */ if (b2 > 0) b <<= b2; @@ -874,7 +933,7 @@ significant digit instead of one half of it when the decimal output string's val if (b.CompareTo(S) < 0) { k--; - b *= 10; /* we botched the k estimate */ + b *= 10; /* we botched the k estimate */ if (leftright) mhi *= 10; ilim = ilim1; @@ -887,8 +946,8 @@ significant digit instead of one half of it when the decimal output string's val /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode. Output either zero or the minimum nonzero output depending on which is closer to d. */ if ((ilim < 0) - || ((i = b.CompareTo(S *= 5)) < 0) - || ((i == 0 && !biasUp))) + || ((i = b.CompareTo(S *= 5)) < 0) + || ((i == 0 && !biasUp))) { /* Always emit at least one digit. If the number appears to be zero using the current mode, then emit one '0' digit and set decpt to 1. */ @@ -896,15 +955,17 @@ Output either zero or the minimum nonzero output depending on which is closer to k = -1 - ndigits; goto ret; */ buf.Length = 0; - buf.Append('0'); /* copy "0" to buffer */ + buf.Append('0'); /* copy "0" to buffer */ return 1; // goto no_digits; } + // one_digit: buf.Append('1'); k++; return k + 1; } + if (leftright) { if (m2 > 0) @@ -923,11 +984,11 @@ Output either zero or the minimum nonzero output depending on which is closer to /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */ /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */ - for (i = 1; ; i++) + for (i = 1;; i++) { BigInteger quotient = BigInteger.DivRem(b, S, out BigInteger remainder); b = remainder; - dig = (char)((int)quotient + '0'); + dig = (char) ((int) quotient + '0'); /* Do we yet have the shortest decimal string * that will round to d? */ @@ -946,19 +1007,22 @@ Output either zero or the minimum nonzero output depending on which is closer to k++; buf.Append('1'); } + return k + 1; // goto round_9_up; } + if (j > 0) dig++; buf.Append(dig); return k + 1; } + if ((j < 0) - || ((j == 0) + || ((j == 0) && (mode == 0) && ((Word1(d) & 1) == 0) - )) + )) { if (j1 > 0) { @@ -967,7 +1031,7 @@ Use whichever would produce a decimal value closer to d. */ b <<= 1; j1 = b.CompareTo(S); if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp))) - && (dig++ == '9')) + && (dig++ == '9')) { buf.Append('9'); if (RoundOff(buf)) @@ -975,17 +1039,21 @@ Use whichever would produce a decimal value closer to d. */ k++; buf.Append('1'); } + return k + 1; // goto round_9_up; } } + buf.Append(dig); return k + 1; } + if (j1 > 0) { if (dig == '9') - { /* possible if i == 1 */ + { + /* possible if i == 1 */ // round_9_up: // *s++ = '9'; // goto roundoff; @@ -995,11 +1063,14 @@ Use whichever would produce a decimal value closer to d. */ k++; buf.Append('1'); } + return k + 1; } - buf.Append((char)(dig + 1)); + + buf.Append((char) (dig + 1)); return k + 1; } + buf.Append(dig); if (i == ilim) break; @@ -1014,12 +1085,12 @@ Use whichever would produce a decimal value closer to d. */ } } else - for (i = 1; ; i++) + for (i = 1;; i++) { // (char)(dig = quorem(b,S) + '0'); BigInteger quotient = BigInteger.DivRem(b, S, out BigInteger remainder); b = remainder; - dig = (char)((int)quotient + '0'); + dig = (char) ((int) quotient + '0'); buf.Append(dig); if (i >= ilim) @@ -1054,6 +1125,7 @@ Use whichever would produce a decimal value closer to d. */ // while(*--s == '0') ; // s++; } + // ret: // Bfree(S); // if (mhi) { @@ -1072,26 +1144,29 @@ private static void StripTrailingZeroes(StringBuilder buf) // while(*--s == '0') ; // s++; int bl = buf.Length; - while (bl-- > 0 && buf[bl] == '0') + while (bl-- > 0 && buf[ bl ] == '0') { // empty } + buf.Length = bl + 1; } /* Mapping of JSDToStrMode -> JS_dtoa mode */ - private static int[] dtoaModes = { - 0, /* DTOSTR_STANDARD */ - 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ - 3, /* DTOSTR_FIXED, */ - 2, /* DTOSTR_EXPONENTIAL, */ - 2}; /* DTOSTR_PRECISION */ + private static int[] dtoaModes = + { + 0, /* DTOSTR_STANDARD */ + 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ + 3, /* DTOSTR_FIXED, */ + 2, /* DTOSTR_EXPONENTIAL, */ + 2 + }; /* DTOSTR_PRECISION */ public static void JS_dtostr(StringBuilder buffer, int mode, int precision, double d) { - int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */ - bool[] sign = new bool[1]; /* true if the sign bit was set in d */ - int nDigits; /* Number of significand digits returned by JS_dtoa */ + int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */ + bool[] sign = new bool[1]; /* true if the sign bit was set in d */ + int nDigits; /* Number of significand digits returned by JS_dtoa */ // JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE : // DTOSTR_VARIABLE_BUFFER_SIZE(precision))); @@ -1099,14 +1174,14 @@ public static void JS_dtostr(StringBuilder buffer, int mode, int precision, doub if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21)) mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */ - decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer); + decPt = JS_dtoa(d, dtoaModes[ mode ], mode >= DTOSTR_FIXED, precision, sign, buffer); nDigits = buffer.Length; /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */ if (decPt != 9999) { bool exponentialNotation = false; - int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */ + int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */ int p; switch (mode) @@ -1160,6 +1235,7 @@ public static void JS_dtostr(StringBuilder buffer, int mode, int precision, doub { buffer.Insert(1, '.'); } + buffer.Append('e'); if ((decPt - 1) >= 0) buffer.Append('+'); @@ -1186,13 +1262,13 @@ public static void JS_dtostr(StringBuilder buffer, int mode, int precision, doub } /* If negative and neither -0.0 nor NaN, output a leading '-'. */ - if (sign[0] && - !(Word0(d) == Sign_bit && Word1(d) == 0) && - !((Word0(d) & Exp_mask) == Exp_mask && - ((Word1(d) != 0) || ((Word0(d) & Frac_mask) != 0)))) + if (sign[ 0 ] && + !(Word0(d) == Sign_bit && Word1(d) == 0) && + !((Word0(d) & Exp_mask) == Exp_mask && + ((Word1(d) != 0) || ((Word0(d) & Frac_mask) != 0)))) { buffer.Insert(0, '-'); } } } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberDiyFp.cs b/src/es6numberserializer/NumberDiyFp.cs index d74d64a4a..3095d8257 100644 --- a/src/es6numberserializer/NumberDiyFp.cs +++ b/src/es6numberserializer/NumberDiyFp.cs @@ -45,7 +45,6 @@ namespace Org.Webpki.Es6NumberSerialization // DiyFp are not designed to contain special doubles (NaN and Infinity). class NumberDiyFp { - private long fv; private int ev; @@ -101,19 +100,19 @@ private void Multiply(NumberDiyFp other) // significant 64 bits are only used for rounding the most significant 64 // bits. const long kM32 = 0xFFFFFFFFL; - long a = (long)((ulong)fv >> 32); + long a = (long) ((ulong) fv >> 32); long b = fv & kM32; - long c = (long)((ulong)other.fv >> 32); + long c = (long) ((ulong) other.fv >> 32); long d = other.fv & kM32; long ac = a * c; long bc = b * c; long ad = a * d; long bd = b * d; - long tmp = ((long)((ulong)bd >> 32)) + (ad & kM32) + (bc & kM32); + long tmp = ((long) ((ulong) bd >> 32)) + (ad & kM32) + (bc & kM32); // By adding 1U << 31 to tmp we round the final result. // Halfway cases will be round up. tmp += 1L << 31; - long result_f = ac + ((long)((ulong)ad >> 32)) + ((long)((ulong)bc >> 32)) + ((long)((ulong)tmp >> 32)); + long result_f = ac + ((long) ((ulong) ad >> 32)) + ((long) ((ulong) bc >> 32)) + ((long) ((ulong) tmp >> 32)); ev += other.ev + 64; fv = result_f; } @@ -140,11 +139,13 @@ public void Normalize() f <<= 10; e -= 10; } + while ((f & kUint64MSB) == 0) { f <<= 1; e--; } + this.fv = f; this.ev = e; } @@ -175,6 +176,5 @@ internal void SetE(int new_value) { ev = new_value; } - } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberDoubleHelper.cs b/src/es6numberserializer/NumberDoubleHelper.cs index 9f31db743..e07c01992 100644 --- a/src/es6numberserializer/NumberDoubleHelper.cs +++ b/src/es6numberserializer/NumberDoubleHelper.cs @@ -38,7 +38,6 @@ namespace Org.Webpki.Es6NumberSerialization { - // Helper functions for doubles. class NumberDoubleHelper { @@ -67,6 +66,7 @@ public static NumberDiyFp AsNormalizedDiyFp(long d64) f <<= 1; e--; } + // Do the final shifts in one go. Don't forget the hidden bit (the '-1'). f <<= NumberDiyFp.kSignificandSize - kSignificandSize - 1; e -= NumberDiyFp.kSignificandSize - kSignificandSize - 1; @@ -77,7 +77,7 @@ public static int Exponent(long d64) { if (IsDenormal(d64)) return kDenormalExponent; - int biased_e = (int)(((d64 & kExponentMask) >> kSignificandSize) & 0xffffffffL); + int biased_e = (int) (((d64 & kExponentMask) >> kSignificandSize) & 0xffffffffL); return biased_e - kExponentBias; } @@ -110,14 +110,14 @@ public static bool IsSpecial(long d64) public static bool IsNan(long d64) { return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) != 0L); + ((d64 & kSignificandMask) != 0L); } public static bool IsInfinite(long d64) { return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) == 0L); + ((d64 & kSignificandMask) == 0L); } @@ -153,12 +153,13 @@ public static void NormalizedBoundaries(long d64, NumberDiyFp m_minus, NumberDiy m_minus.SetF((v.F() << 1) - 1); m_minus.SetE(v.E() - 1); } + m_minus.SetF(m_minus.F() << (m_minus.E() - m_plus.E())); m_minus.SetE(m_plus.E()); } - private const int kSignificandSize = 52; // Excludes the hidden bit. + private const int kSignificandSize = 52; // Excludes the hidden bit. private const int kExponentBias = 0x3FF + kSignificandSize; private const int kDenormalExponent = -kExponentBias + 1; } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberFastDToA.cs b/src/es6numberserializer/NumberFastDToA.cs index dff42a4e5..34c1368e4 100644 --- a/src/es6numberserializer/NumberFastDToA.cs +++ b/src/es6numberserializer/NumberFastDToA.cs @@ -69,11 +69,11 @@ class NumberFastDToA // representable number to the input. // Modifies the generated digits in the buffer to approach (round towards) w. private static bool RoundWeed(NumberFastDToABuilder buffer, - long distance_too_high_w, - long unsafe_interval, - long rest, - long ten_kappa, - long unit) + long distance_too_high_w, + long unsafe_interval, + long rest, + long ten_kappa, + long unit) { long small_distance = distance_too_high_w - unit; long big_distance = distance_too_high_w + unit; @@ -146,10 +146,10 @@ private static bool RoundWeed(NumberFastDToABuilder buffer, // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high // Instead of using the buffer directly we use its distance to too_high. // Conceptually rest ~= too_high - buffer - while (rest < small_distance && // Negated condition 1 - unsafe_interval - rest >= ten_kappa && // Negated condition 2 - (rest + ten_kappa < small_distance || // buffer{-1} > w_high - small_distance - rest >= rest + ten_kappa - small_distance)) + while (rest < small_distance && // Negated condition 1 + unsafe_interval - rest >= ten_kappa && // Negated condition 2 + (rest + ten_kappa < small_distance || // buffer{-1} > w_high + small_distance - rest >= rest + ten_kappa - small_distance)) { buffer.DecreaseLast(); rest += ten_kappa; @@ -159,9 +159,9 @@ private static bool RoundWeed(NumberFastDToABuilder buffer, // would require changing the buffer. If yes, then we have two possible // representations close to w, but we cannot decide which one is closer. if (rest < big_distance && - unsafe_interval - rest >= ten_kappa && - (rest + ten_kappa < big_distance || - big_distance - rest > rest + ten_kappa - big_distance)) + unsafe_interval - rest >= ten_kappa && + (rest + ten_kappa < big_distance || + big_distance - rest > rest + ten_kappa - big_distance)) { return false; } @@ -201,6 +201,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 9; break; } + // else fallthrough goto case 29; case 29: @@ -212,6 +213,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 8; break; } + // else fallthrough goto case 26; case 26: @@ -223,6 +225,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 7; break; } + // else fallthrough goto case 23; case 23: @@ -235,6 +238,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 6; break; } + // else fallthrough goto case 19; case 19: @@ -246,6 +250,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 5; break; } + // else fallthrough goto case 16; case 16: @@ -256,7 +261,8 @@ private static long BiggestPowerTen(int number, int number_bits) power = kTen4; exponent = 4; break; - } // else fallthrough + } // else fallthrough + goto case 13; case 13: case 12: @@ -268,6 +274,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 3; break; } + // else fallthrough goto case 9; case 9: @@ -279,6 +286,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 2; break; } + // else fallthrough goto case 6; case 6: @@ -290,6 +298,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 1; break; } + // else fallthrough goto case 3; case 3: @@ -301,6 +310,7 @@ private static long BiggestPowerTen(int number, int number_bits) exponent = 0; break; } + // else fallthrough goto case 0; case 0: @@ -312,9 +322,10 @@ private static long BiggestPowerTen(int number, int number_bits) power = 0; exponent = 0; break; - // UNREACHABLE(); + // UNREACHABLE(); } - return ((long)power << 32) | (0xffffffffL & exponent); + + return ((long) power << 32) | (0xffffffffL & exponent); } private static bool Uint64_lte(long a, long b) @@ -366,10 +377,10 @@ private static bool Uint64_lte(long a, long b) // represents w. However we have to pay attention to low, high and w's // imprecision. private static bool DigitGen(NumberDiyFp low, - NumberDiyFp w, - NumberDiyFp high, - NumberFastDToABuilder buffer, - int mk) + NumberDiyFp w, + NumberDiyFp high, + NumberFastDToABuilder buffer, + int mk) { Debug.Assert(low.E() == w.E() && w.E() == high.E()); Debug.Assert(Uint64_lte(low.F() + 1, high.F() - 1)); @@ -400,12 +411,12 @@ private static bool DigitGen(NumberDiyFp low, // If we stop early we effectively round down. NumberDiyFp one = new NumberDiyFp(1L << -w.E(), w.E()); // Division by one is a shift. - int integrals = (int)(((ulong)too_high.F() >> -one.E()) & 0xffffffffL); + int integrals = (int) (((ulong) too_high.F() >> -one.E()) & 0xffffffffL); // Modulo by one is an and. long fractionals = too_high.F() & (one.F() - 1); long result = BiggestPowerTen(integrals, NumberDiyFp.kSignificandSize - (-one.E())); - int divider = (int)(((ulong)result >> 32) & 0xffffffffL); - int divider_exponent = (int)(result & 0xffffffffL); + int divider = (int) (((ulong) result >> 32) & 0xffffffffL); + int divider_exponent = (int) (result & 0xffffffffL); int kappa = divider_exponent + 1; // Loop invariant: buffer = too_high / 10^kappa (integer division) // The invariant holds for the first iteration: kappa has been initialized @@ -414,13 +425,13 @@ private static bool DigitGen(NumberDiyFp low, while (kappa > 0) { int digit = integrals / divider; - buffer.Append((char)('0' + digit)); + buffer.Append((char) ('0' + digit)); integrals %= divider; kappa--; // Note that kappa now equals the exponent of the divider and that the // invariant thus holds again. long rest = - ((long)integrals << -one.E()) + fractionals; + ((long) integrals << -one.E()) + fractionals; // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.E()) // Reminder: unsafe_interval.E() == one.E() if (rest < unsafe_interval.F()) @@ -429,9 +440,10 @@ private static bool DigitGen(NumberDiyFp low, // that lies within the unsafe interval. buffer.point = buffer.end - mk + kappa; return RoundWeed(buffer, NumberDiyFp.Minus(too_high, w).F(), - unsafe_interval.F(), rest, - (long)divider << -one.E(), unit); + unsafe_interval.F(), rest, + (long) divider << -one.E(), unit); } + divider /= 10; } @@ -454,19 +466,19 @@ private static bool DigitGen(NumberDiyFp low, fractionals *= 5; unit *= 5; unsafe_interval.SetF(unsafe_interval.F() * 5); - unsafe_interval.SetE(unsafe_interval.E() + 1); // Will be optimized out. - one.SetF((long)((ulong)one.F() >> 1)); + unsafe_interval.SetE(unsafe_interval.E() + 1); // Will be optimized out. + one.SetF((long) ((ulong) one.F() >> 1)); one.SetE(one.E() + 1); // Integer division by one. - int digit = (int)(((ulong)fractionals >> -one.E()) & 0xffffffffL); - buffer.Append((char)('0' + digit)); - fractionals &= one.F() - 1; // Modulo by one. + int digit = (int) (((ulong) fractionals >> -one.E()) & 0xffffffffL); + buffer.Append((char) ('0' + digit)); + fractionals &= one.F() - 1; // Modulo by one. kappa--; if (fractionals < unsafe_interval.F()) { buffer.point = buffer.end - mk + kappa; return RoundWeed(buffer, NumberDiyFp.Minus(too_high, w).F() * unit, - unsafe_interval.F(), fractionals, one.F(), unit); + unsafe_interval.F(), fractionals, one.F(), unit); } } } @@ -494,13 +506,13 @@ private static bool Grisu3(double v, NumberFastDToABuilder buffer) NumberDiyFp boundary_minus = new NumberDiyFp(), boundary_plus = new NumberDiyFp(); NumberDoubleHelper.NormalizedBoundaries(bits, boundary_minus, boundary_plus); Debug.Assert(boundary_plus.E() == w.E()); - NumberDiyFp ten_mk = new NumberDiyFp(); // Cached power of ten: 10^-k + NumberDiyFp ten_mk = new NumberDiyFp(); // Cached power of ten: 10^-k int mk = NumberCachedPowers.GetCachedPower(w.E() + NumberDiyFp.kSignificandSize, - minimal_target_exponent, maximal_target_exponent, ten_mk); + minimal_target_exponent, maximal_target_exponent, ten_mk); Debug.Assert(minimal_target_exponent <= w.E() + ten_mk.E() + - NumberDiyFp.kSignificandSize && - maximal_target_exponent >= w.E() + ten_mk.E() + - NumberDiyFp.kSignificandSize); + NumberDiyFp.kSignificandSize && + maximal_target_exponent >= w.E() + ten_mk.E() + + NumberDiyFp.kSignificandSize); // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a // 64 bit significand and ten_mk is thus only precise up to 64 bits. @@ -512,7 +524,7 @@ private static bool Grisu3(double v, NumberFastDToABuilder buffer) // (f-1) * 2^e < w*10^k < (f+1) * 2^e NumberDiyFp scaled_w = NumberDiyFp.Times(w, ten_mk); Debug.Assert(scaled_w.E() == - boundary_plus.E() + ten_mk.E() + NumberDiyFp.kSignificandSize); + boundary_plus.E() + ten_mk.E() + NumberDiyFp.kSignificandSize); // In theory it would be possible to avoid some recomputations by computing // the difference between w and boundary_minus/plus (a power of 2) and to // compute scaled_boundary_minus/plus by subtracting/adding from @@ -554,7 +566,8 @@ public static bool NumberToString(double v, NumberFastDToABuilder buffer) buffer.Append('-'); v = -v; } + return Dtoa(v, buffer); } } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberFastDToABuilder.cs b/src/es6numberserializer/NumberFastDToABuilder.cs index 305009739..b7cd2952b 100644 --- a/src/es6numberserializer/NumberFastDToABuilder.cs +++ b/src/es6numberserializer/NumberFastDToABuilder.cs @@ -24,12 +24,12 @@ class NumberFastDToABuilder public void Append(char c) { - chars[end++] = c; + chars[ end++ ] = c; } public void DecreaseLast() { - chars[end - 1]--; + chars[ end - 1 ]--; } public void Reset() @@ -43,7 +43,7 @@ public String Format() if (!formatted) { // check for minus sign - int firstDigit = chars[0] == '-' ? 1 : 0; + int firstDigit = chars[ 0 ] == '-' ? 1 : 0; int decPoint = point - firstDigit; if (decPoint < -5 || decPoint > 21) { @@ -53,17 +53,18 @@ public String Format() { ToFixedFormat(firstDigit, decPoint); } + formatted = true; } - return new String(chars, 0, end); + return new String(chars, 0, end); } private void ArrayFill0(int from, int to) { while (from < to) { - chars[from++] = '0'; + chars[ from++ ] = '0'; } } @@ -76,7 +77,7 @@ private void ToFixedFormat(int firstDigit, int decPoint) { // >= 1, split decimals and insert point Array.Copy(chars, point, chars, point + 1, end - point); - chars[point] = '.'; + chars[ point ] = '.'; end++; } else @@ -84,12 +85,13 @@ private void ToFixedFormat(int firstDigit, int decPoint) // < 1, int target = firstDigit + 2 - decPoint; Array.Copy(chars, firstDigit, chars, target, end - firstDigit); - chars[firstDigit] = '0'; - chars[firstDigit + 1] = '.'; + chars[ firstDigit ] = '0'; + chars[ firstDigit + 1 ] = '.'; if (decPoint < 0) { ArrayFill0(firstDigit + 2, target); } + end += 2 - decPoint; } } @@ -108,10 +110,11 @@ private void ToExponentialFormat(int firstDigit, int decPoint) // insert decimal point if more than one digit was produced int dot = firstDigit + 1; Array.Copy(chars, dot, chars, dot + 1, end - dot); - chars[dot] = '.'; + chars[ dot ] = '.'; end++; } - chars[end++] = 'e'; + + chars[ end++ ] = 'e'; char sign = '+'; int exp = decPoint - 1; if (exp < 0) @@ -119,16 +122,17 @@ private void ToExponentialFormat(int firstDigit, int decPoint) sign = '-'; exp = -exp; } - chars[end++] = sign; + + chars[ end++ ] = sign; int charPos = exp > 99 ? end + 2 : exp > 9 ? end + 1 : end; end = charPos + 1; // code below is needed because Integer.getChars() is not internal - for (; ; ) + for (;;) { int r = exp % 10; - chars[charPos--] = digits[r]; + chars[ charPos-- ] = digits[ r ]; exp = exp / 10; if (exp == 0) break; } @@ -139,4 +143,4 @@ private void ToExponentialFormat(int firstDigit, int decPoint) '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; } -} +} \ No newline at end of file diff --git a/src/es6numberserializer/NumberToJson.cs b/src/es6numberserializer/NumberToJson.cs index 94b40de92..069d60c6a 100644 --- a/src/es6numberserializer/NumberToJson.cs +++ b/src/es6numberserializer/NumberToJson.cs @@ -54,10 +54,10 @@ public static string SerializeNumber(double value) { return result; } + StringBuilder buffer = new StringBuilder(); NumberDToA.JS_dtostr(buffer, NumberDToA.DTOSTR_STANDARD, 0, value); return buffer.ToString(); } } -} - +} \ No newline at end of file diff --git a/src/es6numberserializer/es6numberserializer.csproj b/src/es6numberserializer/es6numberserializer.csproj index 5ebf10b90..92ebea7d9 100644 --- a/src/es6numberserializer/es6numberserializer.csproj +++ b/src/es6numberserializer/es6numberserializer.csproj @@ -1,8 +1,8 @@ - - netstandard2.0 - true - + + netstandard2.0 + true + - + \ No newline at end of file