Giter Site home page Giter Site logo

eclipse-aaspe / aasx-server Goto Github PK

View Code? Open in Web Editor NEW
64.0 14.0 46.0 40.04 MB

C# based server for AASX packages

License: Other

C# 92.51% HTML 5.36% CSS 0.04% Shell 0.01% PowerShell 0.14% Batchfile 0.01% Logos 1.89% Java 0.06% Dockerfile 0.01%
aasx administration-shell aasx-server asset-administration-shell industrie-40 industrie40

aasx-server's Introduction

Warning

This repository has been moved alongside Eclipse AASX Package Explorer to the eclipse-aaspe organisation.
Branches and issues will be unaffected. All links to the previous repository location are automatically redirected to the new location, e.g. when using git clone, git push etc. It is, however, recommended to update the origin of any clones to avoid confusion.

Eclipse AASX Server

Check-release-workflow Check-style-workflow Build-and-package-release-workflow Build-and-publish-docker-images-workflow

AASX Server is a companion app for AASX Package Explorer. It provides a local service to host and serve Industrie 4.0 AASX packages. The Core version exposes endpoints for REST, OPC UA and MQTT protocols. The GUI version offers the same functionality and additionally uses Blazor Framework to provide a GUI in the browser for exploring AASX Packages.

Important

AASX Server is now V3 and branch main includes a first release:
https://github.com/admin-shell-io/aasx-server/releases/tag/v2023-09-13.alpha
The latest work takes place in branch policy3, which will be included in main then.

Tip

A demo server is running on https://v3.admin-shell-io.com.
https://v3.admin-shell-io.com/swagger shows the API and you can try it manually.
An AASX Server with security enabled can be found here: https://v3security.admin-shell-io.com/.

How-to

Mainly AasxServerBlazor is currently used, but AasxServerCore will also be supported.
AasxServerWindows will not be further developed, since .NET 6 works well also on Windows.
--rest, --host, --port are no more supported and will be removed soon. This was the old V2 API.
Please ignore the "Connect to REST by:" message.

Maybe you put your AASXs into ./aasxs.
In the examples below please change YOURPORT and YOURURL.

You may run AASX server directly by dotnet:

export DOTNET_gcServer=1  
export Kestrel__Endpoints__Http__Url=http://*:YOURPORT  
dotnet AasxServerBlazor.dll --no-security --data-path ./aasxs --external-blazor YOURURL  

(ASP.NET Core Runtime 6.0 can be downloaded here: https://dotnet.microsoft.com/en-us/download/dotnet/6.0)

The related docker is:
docker.io/adminshellio/aasx-server-blazor-for-demo:main

Put your AASXs into ./aasxs and you may run the docker by e.g.:

docker run  
-p 5001:5001  
--restart unless-stopped  
-v ./aasxs:/AasxServerBlazor/aasxs  
docker.io/adminshellio/aasx-server-blazor-for-demo:main  

If you like to use docker compose, see docker-compose.yaml below.

services:  
  aasx-server:  
    container_name: aasx-server  
    image: docker.io/adminshellio/aasx-server-blazor-for-demo:main  
    restart: unless-stopped  
    ports:  
      - YOURPORT:5001  
    environment:  
      - Kestrel__Endpoints__Http__Url=http://*:5001  
    volumes:  
      - ./aasxs:/usr/share/aasxs  
    command: --no-security --data-path /usr/share/aasxs --external-blazor YOURURL  

The V3 also has a first basic implementation of persistence in a database. We are using the Entity Framework, which has been tested with SQLite and PostgreSQL. SQLite is part of the standard deployment. (PostgreSQL will be explained in the README later in the future.)

Add --with-db to turn on database storage. For the first start please add "--start-index 0" to get the AASX files in --data-path imported into the database. For further starts add "--start-index number" with number greater than you number of AASX files, e.g. 1000. If you change content by the API, you may add "--save-temp number_of_seconds" and the changes will written to the database after the number_of_seconds. With "--aasx-in-memory number" you can specifiy how many AAS shall be shown in the blazor tree. Only the latest changed AAS will be shown.

You can find an example server with database running here: https://cloudrepo.h2894164.stratoserver.net The database content can be seen here: https://cloudrepo.h2894164.stratoserver.net/db . Click on the links on the right. You may also do GraphQL queries to the database here: https://cloudrepo.h2894164.stratoserver.net/graphql/ On the graphql page enter { followed by a space and the wizard will lead you further. An example graphql query is: { searchSubmodels (semanticId: "https://admin-shell.io/zvei/nameplate/1/0/Nameplate") { submodelId url } }

If you want to createa registry and also automatically POST to it, please take a look at: #189

OLD DOCUMENTATION

This documentation will be updated to V3 soon.

AASX Server serves Industrie 4.0 AASX packages accessible by REST, OPC UA and MQTT protocols.

The AASX Server is based on code of AASX Package Explorer ( https://github.com/admin-shell-io/aasx-package-explorer ).

There are three variants of the server:

  • blazor. This variant uses Blazor framework to provide a graphical user interface in the browser for exploring the AASX packages. The other APIs are the same as in the core variant.

  • core. This is a server based on .NET Core 3.1.

  • windows. This variant uses .NET Framework 4.7.2, which is the only way how you can start a server on your Windows machine without administrator privileges. If you run on windows start with this variant first and try blazor later.

    Mind that blazor and core variants require administrator privileges, so they can not be used for demonstration purposes on tightly-administered machines (which are wide-spread in larger organizations and enterprises).

A blazor demo server is running on https://admin-shell-io.com/5001/. Please click on an AAS and use the DOWNLOAD button on the right or use "https://admin-shell-io.com/51411/server/getaasx/0" etc. by browser or CURL on the command line. You can connect to this AASX Server by AASX Package Explorer by "File / AASX File Repository / Connect HTTP/REST repository" with REST endpoint "https://admin-shell-io.com/51411".

Binaries

The binaries are available in the Releases section. We provide portable dotnet assemblies.

Installation

AASX Server depends on .NET Core 3.1 runtime (blazor and core variants) and .NET Framework (windows variant), respectively. You need to install the respective runtimes before you start the server. .NET framework is part of windows. See https://dotnet.microsoft.com/download/dotnet-core/3.1

To deploy the binaries, simply extract the release bundle (e.g., AasxServerWindows.zip or AasxServerCore.zip) somewhere on your system.

Running for Demonstration

We include an example AASX and various extra files (e.g., certificates) in the release bundle so that you can readily start the server for demonstration purposes. The scripts startForDemo.sh and startForDemo.bat will start the server with these pre-packaged files.

For example, if you run on Linux, change to the directory where you extracted the release bundle and invoke:

./startForDemo.sh

On Windows please start startForDemo.bat.

We provide a couple of sample admin shells (packaged as .aasx) for you to test and play with the software at: http://www.admin-shell-io.com/samples/. Please copy these to the aasxs subdirectory as needed.

Running on Windows

Change to the directory where you extracted the release bundle.

Start startForDemo.bat or invoke the executable with the same name as the server variant. For example:

AasxServerWindows.exe --opc --rest -data-path /path/to/aasxs

You can see the AAS on the server with: http://localhost:51310/server/listaas. To show the JSON of the exampleMotor AAS please use: http://localhost:51310/aas/ExampleMotor. To show submodel "Identification" please use: http://localhost:51310/aas/ExampleMotor/submodels/Identification/complete.

Options

To obtain help on individual flags and options, supply the argument --help:

AasxServerWindows.exe --help or AasxServerCore.exe --help

AasxServerCore:
  serve AASX packages over different interfaces

Usage:
  AasxServerCore [options]

Options:
  -h, --host <host>                      Host which the server listens on [default: localhost]
  -p, --port <port>                      Port which the server listens on [default: 51310]
  --https                                If set, opens SSL connections. Make sure you bind a certificate to the port before.
  --data-path <data-path>                Path to where the AASXs reside
  --rest                                 If set, starts the REST server
  --opc                                  If set, starts the OPC server
  --mqtt                                 If set, starts a MQTT publisher
  --debug-wait                           If set, waits for Debugger to attach
  --opc-client-rate <opc-client-rate>    If set, starts an OPC client and refreshes on the given period (in milliseconds)
  --connect <connect>                    If set, connects to AAS connect server. Given as a comma-separated-values (server, node name, period in milliseconds) or as a flag (in which case it connects to a default server).
  --proxy-file <proxy-file>              If set, parses the proxy information from the given proxy file
  --no-security                          If set, no authentication is required
  --edit                                 If set, allows edits in the user interface
  --name <name>                          Name of the server
  --version                              Show version information
  -?, -h, --help                         Show help and usage information

Running on Linux

Change to the directory where you extracted the release bundle.

Start startForDemo.bat or use dotnet to execute the DLL with the same name as the server variant. For example:

dotnet AasxServerCore.dll --opc --rest --data-path /path/to/aasxs

Mono

You can use AasxServerWindows with Mono. Change to the directory where you extracted the release bundle. Use mono to execute the EXE:

mono AasxServerWindows.exe --rest --data-path /path/to/aasxs

If you want to also use "--opc" with Mono you need to change Opc.Ua.SampleServer.Config.xml: change <StoreType>X509Store</StoreType> to <StoreType>Directory</StoreType>.

Mono gives you the possibility to run AasxServer on platforms like x86, PowerPC or MIPS.

See supported Mono platforms on: https://www.mono-project.com/docs/about-mono/supported-platforms/

Find Mono downloads on: https://www.mono-project.com/download/stable/

Build and Package Binaries

To build the binaries from the source code, run the powershell script src/BuildForRelease.ps1.

To package the binaries for release, call src/PackageRelease.ps1.

For more information on continuous integration, see .github/workflows/build-and-package-release.yml for a workflow executed on each release and .github/workflows/check-release.yml for a workflow which is executed on each push to master branch.

Docker Containers for Demonstration

We provide pre-built docker images meant for demonstration purposes at the following DockerHub repositories:

In case you want to deploy on Raspberry PI, you probably need to use ARM 32-bit.

Ideally, we would like to set up a multi-arch docker container (see this article). If you have experience with multi-arch images and would like to help, please let us know by creating an issue.

For example, to pull the latest core variant of the server for the demonstration on a x86 64-bit machine (linux/amd64), invoke:

docker pull adminshellio/aasx-server-core-for-demo

You can then run the container with:

docker run \
    --detach \
    --network host \
    adminshellio/aasx-server-core-for-demo

The server should be accessible now on your localhost. For example, curl:

curl http://localhost:51310/server/listaas

should give you something like this:

{
  "aaslist": [
    "0 : ExampleMotor : [IRI] http://customer.com/aas/9175_7013_7091_9168 : ./aasxs/Example_AAS_ServoDCMotor_21.aasx"
  ]
}

As you can see, we already provide an example AASX in the container. For a more thorough demo, you might want to copy additional AASX packages (e.g., from the samples) into the container. Find the container ID of your running container with:

docker ps

Then use docker cp to copy the AASX packages into the aasxs directory (assuming your docker container ID is 70fe45f1f102):

docker cp /path/to/aasx/samples/  70fe45f1f102:/AasxServerCore/aasxs/

If you demo with blazor variant, change the destination path analogously to AasxServerBlazor.

For example a docker with blazor may be startet by

docker run -p 51000:51310 -p 51001:5001 -v ~/samples:/AasxServerBlazor/aasxs adminshellio/aasx-server-blazor-for-demo
/AasxServerBlazor

connecting host port 51000 to REST port 51310 and host port 51001 to blazor view port 5001. In addition the host directory ~/samples is used to load .AASX files from inside the docker.

Mind that there are many other options for managing containers for custom demos such as Docker multi-stage builds (using one of our demo images as base), bind mounts etc.

Build Docker Containers for Demonstration on Linux/MacOS

We provide a powershell script to build the docker containers meant for demonstrations at src/BuildDockerImages.ps1.

Basic API

Please find a short description of the REST API below.

{aas-identifier} = idShort of AAS
{submodel-identifier} = idShort of Submodel
{se-identifier} = idShort of SubmodelElement
{sec-identifier} = idShort of SubmodelElementCollection

Asset Administration Shell Repository Interface

Cmd String Example
GET /server/profile http://localhost:51310/server/profile
GET /server/listaas http://localhost:51310/server/listaas

Asset Administration Shell Interface

Cmd String Example
GET /aas/{aas-identifier}
/aas/{aas-identifier}/core
/aas/{aas-identifier}/complete
/aas/{aas-identifier}/thumbnail
/aas/{aas-identifier}/aasenv
http://localhost:51310/aas/ExampleMotor
http://localhost:51310/aas/ExampleMotor/core
http://localhost:51310/aas/ExampleMotor/complete
http://localhost:51310/aas/ExampleMotor/thumbnail
http://localhost:51310/aas/ExampleMotor/aasenv

Submodel Interface

Cmd String
GET /aas/{aas-identifier}/submodels/{submodel-identifier}
/aas/{aas-identifier}/submodels/{submodel-identifier}/core
/aas/{aas-identifier}/submodels/{submodel-identifier}/deep
/aas/{aas-identifier}/submodels/{submodel-identifier}/complete
/aas/{aas-identifier}/submodels/{submodel-identifier}/table

Example: http://localhost:51310/aas/ExampleMotor/submodels/Documentation/complete

Submodel Element Interface

Cmd String
GET /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}/core
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}/complete
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}/deep
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}/value
PUT /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/ + Payload
Payload = content of "elem"-part of a SubmodelElement (see example below)
DELETE /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{se-identifier}

Example: http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeed/complete

Submodel Element Collection Interface

Cmd String
GET /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}/core
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}/complete
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}/deep
/aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}/value
PUT /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier} + Payload
Payload = content of "elem"-part of a SubmodelElement (see example below)
DELETE /aas/{aas-identifier}/submodels/{submodel-identifier}/elements/{sec-identifier}/{se-identifier}

Example: http://localhost:51310/aas/ExampleMotor/submodels/Documentation/elements/OperatingManual/DocumentId/complete

Example: PUT SubmodelElement

PUT http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements
Payload:

{
    "value": "1234",
    "valueId": null,
    "semanticId": {
      "keys": [
        {
          "type": "ConceptDescription",
          "local": true,
          "value": "http://customer.com/cd//1/1/18EBD56F6B43D895",
          "index": 0,
          "idType": "IRI"
        }
      ]
    },
    "constraints": [],
    "hasDataSpecification": [],
    "idShort": "RotationSpeedNEW",
    "category": "VARIABLE",
    "modelType": {
      "name": "Property"
    },
    "valueType": {
      "dataObjectType": {
        "name": "integer"
      }
    }
}

Test with: GET http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeedNEW

Issues

If you want to request new features or report bugs, please create an issue.

Contributing

Code contributions are very welcome! Please see CONTRIBUTING.md for more information.

aasx-server's People

Contributors

abroering avatar alexanderwollbrink avatar aorzelskigh avatar br-iosb avatar dependabot[bot] avatar dschubertpxc avatar g1zzm0 avatar gbrost avatar harishpakala avatar jjtikekar avatar juileetikekar avatar magnus-redeker avatar martafullen avatar michaelhoffmeisterfesto avatar mristin avatar saidta avatar stengruener avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aasx-server's Issues

Unable to run AASX server

Hi Team,

I am facing problem with running the application. Getting Uncaught SyntaxError: Unexpected token '}'
aasxServerError

Ctrl-C does not send SIGKILL

When using the binaries I have not been able to exit the application with CTRL-C. I rather have to close the terminal. Is this a bug or is there a way to know why this is not working on my end.

regards

AASX File Download

For the industrial use-case the type AAS needs a mandatory version information in both the aasx file and in the server responses.
i.e If a file download is generated from the AASX server, the file content needs to be exact the same as the published file.
This is currently not true in branch erichb-masterv3.

Is there a specific version information defined for the aasx file and the AAS itself?

API Documentation

It is possible to add some documentation on the REST API provided with the server if present?

Some minimal documentation can be founded on the previous repository but not detailed enough to be really useful.

Typo in route of upload attachment to submodel element endpoint

In the latest release there is a typo in the route of the endpoint that uploads attachments to submodel elements in SubmodelRepositoryAPI controller.
It should be submodels/{submodelId}/submodel-elements/{idShortPath}/attachment but currently it is submodels/{submodelId}/submodelelements/{idShortPath}/attachment which is not conformant with the standard.

OPC Server start failure

OPC Server start failed on both windows and blazor versions

Error:

Application startup exception: System.MissingMethodException: Method not found: 'Void Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.set_NoDelay(Boolean)'.
   at Opc.Ua.Bindings.UaHttpsChannelListener.<>c__DisplayClass7_0.<Start>b__1(ListenOptions listenOptions)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPEndPoint endPoint, Action`1 configure)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPAddress address, Int32 port, Action`1 configure)
   at Opc.Ua.Bindings.UaHttpsChannelListener.<>c__DisplayClass7_0.<Start>b__0(KestrelServerOptions options)
   at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, IConnectionListenerFactory transportFactory, ILoggerFactory loggerFactory)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.AspNetCore.Hosting.WebHost.EnsureServer()
   at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()

My .net env:

Host:
  Version:      6.0.9
  Architecture: x86
  Commit:       163a63591c

.NET SDKs installed:
  No SDKs were found.

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.29 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.9 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.29 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.9 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files (x86)\dotnet\shared\Microsoft.WindowsDesktop.App]

Tried to use Beckhoff OPC UA Client connect to port 51310 but failed:

Error while loading endpoints - BadSecureChannelClosed

Route Not Found For GET /

I cannot start the server with the demo configuration (startFordemo.bat).

This is the output of the executable

AasxServerCore.exe --rest --no-security --data-path aasxs
Serving the AASXs from: aasxs
Security 1 Startup - Server
Security 1.1 Load X509 Root Certificates into X509 Store Root
Loading aasxs\Example_AAS_ServoDCMotor_21.aasx...

Please wait for the servers to start...
Connect to REST by: localhost:51310
http://localhost:51310/
REST Server started.
Test: ../proxy.dat
Servers successfully started. Press Ctrl-C to exit...

localhost server output in browser

Route Not Found For GET /
<br>
   at Grapevine.Server.Router.Route(IHttpContext context, IList`1 routing)
   at Grapevine.Server.Router.Route(Object state)

Closed this issue as I forgot to add the endpoint of the API as mentioned in the readme

http://localhost:51310/server/listaas

Uploading files to an AAS does not update the underlying package

Branch: masterV3

When using the REST API to upload attachments or thumbnails into an existing AAS this does not update the underlying package.
We always need to download the package and afterwards upload it again (using the PUT /packages/{packageID} endpoint) to make the changes permanent.

Is this the intendend behaviour or should adding files via REST API automatically update the stored AASX package?

Edit:

There is a bug when editing an AASX with the PUT package endpoint after a change was done to the original AASX file.
I think a proper fix should be changing this line

https://github.com/admin-shell-io/aasx-server/blob/3abf7f1817bf5118293e1b2b7daddb864b1fac71/src/IO.Swagger.V1RC03/Services/AasxFileServerInterfaceService.cs#L194

into this

var originalFile = _envFileNames[packageIndex];

Aasx-Server does not communicate with other devices (clients) through API Gateway or OPC UA.

Aasx-Server does not communicate with other devices (clients) through API Gateway or OPC UA.

All devices are connected to the same network (192.168.1.xxx).
When I execute AASX-SERVER on my laptop (IP: 192.168.1.104)

~/AasxServerCore.2022-07-25.alpha\AasxServerCore>AasxServerCore.exe --rest --opc --mqtt --edit --no-security --data-path aasxs
Serving the AASXs from: aasxs
Security 1 Startup - Server
Security 1.1 Load X509 Root Certificates into X509 Store Root
Connect to OPC UA by: opc.tcp://0.0.0.0:51210/UA/SampleServer
Loading aasxs\15_Siemens.aasx...
Loading aasxs\Example_AAS_ServoDCMotor_21.aasx...
Loading aasxs\Wika_PSD4.aasx...

Please wait for the servers to start...
Connect to REST by: localhost:51310
http://localhost:51310/
REST Server started.
MQTT Publisher started.
OPC UA Server started..
Servers succesfully started. Press Ctrl-C to exit...

I can access the server normally at the address http://localhost:51310/server/listaas in the same laptop (IP: 192.168.1.104) that I run the server.

~/ curl http://localhost:51310/server/listaas
{
  "aaslist": [
    "0 : Siemens_S7_CPU1515 : [IRI] www.company.com/demo/aas/1234554842136874684321 : aasxs\\15_Siemens.aasx",
    "1 : ExampleMotor : [IRI] http://customer.com/aas/9175_7013_7091_9168 : aasxs\\Example_AAS_ServoDCMotor_21.aasx",
    "2 : Wika_PSD4_1 : [IRI] https://example.com/ids/ass/0330_9101_5032_3395 : 
aasxs\\Wika_PSD4.aasx"
  ]
}

But when I try to access another computer or device like Raspberry PI (IP: 192.168.1.114), the server created in the laptop (IP: 192.168.1.104) does not respond.

pi@raspberrypi:~ $ curl http://192.168.1.104:51310/server/listaas
... (does not respond or do not return anything)

I also tried to use the --host option (IP: 192.168.1.104) and was unsuccessful either.

I surrounded other aasx-server versions such as aasxservercore.2022-01-13.alpha and the same problem persists.

The same type of problem happens when trying to access the AASX-SERVER through the OPC UA, being possible only connect and view in the same machine (OPC.TCP: // localhost: 51210/UA/SampleServer), if I try to access another device,and take a search in the same option it does not even find the correct IP of the laptop (OPC.TCP: //192.168.1.104: 51210/UA/SampleServer) on the OPC UA client.

Implement archive validation

I think it whould be nice to have a aasx archive validate-against-specification feature as implemented in [1]. I propose one of the following implementations, or maybe a combination, the the user can switch strict/loose by command line option or similar:

  1. be strict
  • validate all files given in the input directory
  • show files that pass validaton
  • ignore and log files that don't pass validation
  1. be loose
  • take all aasx files from input directory
  • show contents if possible, log errors
  • implement a validation endpoint (e.g. GET /aasx/{id}/valiate) showing validation success/errors in object to be returned to the client
/// <summary>
/// validation class, contains file and valdation status information as well as an optional list of errors found in the file
/// </summary>
public class ValidationStatus
{
    /// <summary>
    /// the numeric id of the aasx file
    /// </summary>
    [Required]
    public long Id { get; set; }

    /// <summary>
    /// the validation status of the given aasx file
    /// </summary>
    [Required]
    public bool Valid { get; set; }

    /// <summary>
    /// the list of errors found in the aasx file
    /// </summary>
    public IList<ValidationError>? Errors { get; set; } = null;
}

/// <summary>
/// validation error class, contains error information for a specific error found in the parsed aasx file
/// </summary>
public class ValidationError
{
    /// <summary>
    /// the line containing the error
    /// </summary>
    [Required]
    public long Line { get; set; }

    /// <summary>
    /// the exact error found in that line
    /// </summary>
    [Required]
    public ErrorType Type { get; set; }

    /// <summary>
    /// a meaningfull description of the error, should be human-readable
    /// </summary>
    [Required]
    public string Description { get; set; }

    /// <summary>
    /// optional debugging message (for development  purposes)
    /// </summary>
    public String? DebugMessage { get; set; }
}

/// <summary>
/// enum containing all implemented error types, to the error output can be machine-readable
/// </summary>
public enum ErrorType
{
    /// <summary>
    /// thrown when a (sub) element is missing
    /// </summary>
    MissingElement,

    /// <summary>
    /// thrown when a (sub) element is unexcpeted
    /// </summary>
    ExtraElement,
    
    /// <summary>
    /// thrown when a value of an element cannot be parsed
    /// </summary>
    ParseError,

    /// <summary>
    /// thrown when an element in the file is unspecified
    /// </summary>
    UnknownElement

    // to be continued
}

[1] https://git.rwth-aachen.de/acplt/pyi40aas

AAS Events - propagate changes between Package Explorers via AAS Server

Is it possible to use AAS Events to propagate the updated value of a property from one instance of the Package Explorer to another, via an AAS Server.
To clarify the two Package Explorers are connected via REST to the same server and viewing the same AAS, a change is made to a property in one Package Explorer, saved back to the server, should the second Package Explorer update the property?
From the specification it looks as if it should be possible, but when I tried it, it did not work.

Request Body for POST /shell-descriptors

How do I set the Request Body for POST /shell-descriptors?
I would like a concrete example. I don't know the relationship with the existing Example_AAS_ServoDCMotor_21.aasx file.
Does anyone know?
I don't understand as there is no detailed description in IDTA-01002-3-0_SpecificationAssetAdministrationShell_Part2_API.pdf.
I would like to know more about AssetAdministrationShellRegistryAPIApi.

Download non-existent file from aasx archive broken

When trying to download a non-existing file from an archive the REST server part throws an exception and sends the exception message with HTTP status code 200 to the client.

I suggest, the REST server should send a 404 HTTP status code. The exception message should be logged, not sent to the client. Maybe it would be a nice idea to to have a configurabe error json object to be send to the client in case of an error; the object could include the exception message for development purposes or internal usage.

The missing/broken error handling seems to be related to #58

Adding information to submodell/AAS (specifically in OPC UA)

I want to use OPC UA as default connectivity to the Asset Administration Shells. I need to add nodes while the Application is running.
Right now I'm not sure if I need to change the Server or Client Application. Since I want to add information from the Client it should be the client, but this could result in harming the structure of the AAS, proably there should be a Methode to add information to the AAS. and if the serialized data isn't correct or incomplete the server should denie the request.

Where should I try to add nodes to the server?

I would appreciate some other thoughts about this.

How to Update Property from ExampleMotor via PUT

I am trying to check how to update properties via the HTTP/REST API but I have not been able to do it properly.

I tried the following PUT request to update the OperationalData submodel property RotationSpeed but it did not work.

Request URL

http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeed

Payload

{
    "value": "1234"
}

Response

Matching SubmodelElement in Submodel OperationalData is not suitable to add childs.

Keycloak Setup

Hey there,

For the use of the AASX-server in the SDM4FZI-project, I want to deploy an AASX-server in a Kubernetes cluster and use keycloak for authentication. However, I am wondering how to configure the server so that I can use keycloak.
Is there any documentation or guide on how to achieve this?
Would be great, if you could help me out.

The docker container must be restarted in order to refresh the availble models

Hi everyone

There seem to be a problem when it comes to refreshing the content onthe Blazor GUI. When new models are added to "/AasxServerBlazor/aasxs/" , they do not show up automatically as expected and the container must be restarted in order for that to happen.
I have tried with both volumes and bind-mounts to no avail

Bill of material and Reference

If the submodel Bill of material is created and populated with Self managed Entities the relation between the Element in the Bill of material Submodel and the referred AAS should be managed by the server.

In this way by clicking on the reference the corresponding AAS should open and the navigation between them for the user is simplified.

Immagine 2020-11-05 171750

can we have submodels with the same IdShort in an AAS?

Hello!

I'm trying to represent the "WebService" submodel for the scenario: "A device can offer multiple web services".
The AASX Package Explorer allows me to create many submodels with the same IdShort (WebService), but the AASX-Server's API only returns the first record:
/aas/{aas-identifier}/submodels/{submodel-identifier}

Is it an issue or I'm not in the right direction? Please help

Serialization and deserialization of AasCore.Aas3_0_RC02.LangString are inconsistent

Description

Branch: masterV3
Serialization and deserialization of type AasCore.Aas3_0_RC02.LangString are done in a different way.

Example

When creating an AAS or submodel and setting a language string, for instance on the property displayName or description it is necessary to use an JSON array, containing AasCore.Aas3_0_RC02.LangString objects.

"description": [
    {
        "language": "en",
        "text": "English Text "
    }
]

When querying data from the server, the format is different. There is another object langStrings introduced, containing the langugage string array. This was also the case in previous versions.

"description": {
    "langStrings": [
        {
            "language": "en",
            "text": "English Text "
        }
    ]
},

At least on point should be changed because the latest Swagger API definition also does not contain the extra langStrings object. Handling serialization and deserialization would make things unnecessarily complex.

Return actual AASX file when downloading via GET /server/getaasx/{ID}

Hi,

while testing the download feature of the REST server part, I figured the aasx file is somehow rebuilt for download. At least the xml part is rewritten.

This will fail, if a signed aasx file is downloaded, since the signature verification of the downloaded file will most likely fail (except for the case the rebuilt xml matches exactly the original one). Also, it simply seems odd the downloaded file does not match the original one.

I suggest, the download endpoint should just take the aasx file from the input folder and send it to the client as is.

Operation without inputs or outputs cannot be created via REST API

Missing null check in many functions using FindAAS

In AasxHttpContextHelper.cs the FindAAS function is used in several places without checking if the return object is null.

For example:

var findAasReturn = this.FindAAS(aasid, context.Request.QueryString, context.Request.RawUrl);
if (findAasReturn.aas == null)
{
    context.Response.SendResponse(HttpStatusCode.NotFound, $"No AAS with idShort '{aasid}' found.");
    return;
}

If the AAS cannot be found, the FindAAS function either returns null directly or a FindAasReturn.aas which is null.

Due to the missing null check the REST server breaks:
curl -v http://localhost:51310/aas/123
Output:

> GET /aas/123 HTTP/1.1
> Host: localhost:51310
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 Ok
< Server: Grapevine/4.1.2.0
< Date: Mon, 08 Feb 2021 21:37:14 GMT
< Content-Length: 703
< 
Exception has been thrown by the target of an invocation.
<br>
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Grapevine.Server.Route.<>c__DisplayClass42_0.<ConvertMethodToFunc>b__1(IHttpContext context)
   at Grapevine.Server.Route.Invoke(IHttpContext context)
   at Grapevine.Server.Router.Route(IHttpContext context, IList`1 routing)
* Connection #0 to host localhost left intact
   at Grapevine.Server.Router.Route(Object state)

an attached container ignores signals from terminal (e.g. ctrl+c)

Hi everyone,

when I start an attached container with:

docker run --name assx-server --rm adminshellio/aasx-server-blazor-for-demo

logs tell me I can stop the server with ctrl+c.
image
And it's common for containers to react to these signals, e.g. ctrl+x

PROBLEM: But the container doesn't react to any input and therefore cannot be stopped directly.

I always need to stop the container on another shell with docker stop assx-server
The same thing happens when I start the container with the -it flags.

Maybe this answer can also be helpful. https://stackoverflow.com/a/41099052

REST-Api: GET shells/{aasId as base64url} returns InternalServerError

I'm running the latest Blazor-Release as a docker container.
The gui interface seems to be working.

When I try the following:

  • GET /shells
  • base64url encode the "id" property of the first available AAS
  • GET /shells/{id}

I get the following response:

{
    "messages": [
        {
            "code": "InternalServerError",
            "correlationId": null,
            "messageType": "Error",
            "text": "Object reference not set to an instance of an object.",
            "timestamp": "10/13/2023 07:10:10"
        }
    ]
}

Does anyone have an idea if I'm doing anything wrong?

Missing query parameters for /shells/{aasIdentifier}/submodels

Describe the bug
Branch masterV3 provides a resource /shells/{aasIdentifier}/submodels which should include the same query parameters as for /submodels.

/shells/{aasIdentifier}/submodels:

image

/submodels:

image

At the moment it is not possible to request a specific submodel of a AAS by semanticID or idShort.

Docker image and source code not same

I would like to ask how often is docker images are refreshed. Because we have found out that there is a big discrepancy between docker latest image and main source code. When i tried to create a submodel using docker image running on my mac, it was working fine but exact the same client code, I have executed downloading the latest main source code and running in VS 2022, it threw an exception.
So obviously docker image was not up-to-date.

Feature Request: Write to OPC Server and synchronization

Hello, is there a way to make the values in the OPC Server writeable? Currently it is read-only. Another nice feature would be that the OPC Server updates when changes through the REST API are made. For example, if I delete a submodel with the REST API, it could also be deleted in the OPC Server.

Infos about MQTT usage

I can not find any information about the usage of the mqtt publisher, like topic and subsriber information. Please provide some documentation.

Aasx-server and aasx-code3.0 Verify conflict

In general there aasx-server source code has problem with the sub list when they are null, it crashes or silently failing. For example, we have found out that when submodels list is "null" for created shell it crashes. see the image below
MicrosoftTeams-image

but then when you create an empty list, Verify, you get error as below
"Invariant violated:
Statements must be either not set or have at least one item."

var verifyResultErrors = Verification.Verify(submodel);

So it makes verification not useful. I believe here verify method doest correct job while aasx-server code should make a null check in general.

How to PUT an Aasx File on Server by REST API?

image
When I try to PUT an Aasx File to replace the Example Motor, I got this.
I'm confused about what form the http body should be?
Thank you.
Error Message:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

REST-OPC UA-Synchronization

Hi everyone,
there seemts to be an issue when both REST- and OPC UA-server are started serving an AAS including submodels.
When, for example, the value of a property is editted via REST-API, the corresponding OPC UA node seems not to take over the new value.
Could you please have a look at it?
Might there be something similar to Blazor's Program.signalNewData() function?
Regards, Magnus

The docker image doesn't expose the web UI

Hi,
I'm following your description in the README.md how to start the Blazor server, using:
docker run -p 51000:51310 -p 51001:5001 adminshellio/aasx-server-blazor-for-demo

The REST server is working, but the blazor Web UI is not working.
In the corresponding Dockerfile, the exposed ports are 51310 and 51210.

Can you please check and give me some advice how to continue?

Best regards,
Emil

Is it possible to add an AASX package via the API?

I read the README.md file and saw the API for this project. Is it possible to upload a package to the server via the API or can it only be done via the package explorer?

Please correct me if I am wrong as I am new to the Asset administration shell.

ValueType is not correctly stored when using the PUT-SubmodelElement-Example

I want to add a SubmodelElement to my AAS. I first tried your example to add the new Property RotationSpeedNEW:

PUT http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements
Payload:

{
    "value": "1234",
    "valueId": null,
    "semanticId": {
      "keys": [
        {
          "type": "ConceptDescription",
          "local": true,
          "value": "http://customer.com/cd//1/1/18EBD56F6B43D895",
          "index": 0,
          "idType": "IRI"
        }
      ]
    },
    "constraints": [],
    "hasDataSpecification": [],
    "idShort": "RotationSpeedNEW",
    "category": "VARIABLE",
    "modelType": {
      "name": "Property"
    },
    "valueType": {
      "dataObjectType": {
        "name": "integer"
      }
    }
}

This all worked fine and the Property was added to the AAS. But when looking in detail in the new entry it looks like the valueType is not correctly stored in the AAS because it is empty. This is my result of the

GET http://localhost:51310/aas/ExampleMotor/submodels/OperationalData/elements/RotationSpeedNEW

Result:

{
  "elem": {
    "value": "1234",
    "valueId": null,
    "semanticId": {
      "keys": [
        {
          "type": "ConceptDescription",
          "local": true,
          "value": "http://customer.com/cd//1/1/18EBD56F6B43D895",
          "index": 0,
          "idType": "IRI"
        }
      ]
    },
    "constraints": [],
    "hasDataSpecification": [],
    "idShort": "RotationSpeedNEW",
    "category": "VARIABLE",
    "modelType": {
      "name": "Property"
    },
    "valueType": {
      "dataObjectType": {
        "name": ""
      }
    },
    "kind": "Instance",
    "descriptions": null
  },

There you can see that valueType.dataObjectType.name is empty but in the payload of the PUT-Request it was defined as integer.

Can anyone please help me why this is happening?

Allow traversal of entities

Currently only SubmodelElementCollections and Operation can be traversed in the HTTP API, but the Entity statements should also be able to traverse easily in the API.

I will link an pull request with an implementation of this feature

Connectivity between Package Explorer and AASX Server

Hello, it is possible to build up a connection from the Package Explorer to the AASX Server to add further AAS into the designated directory. Which kind of connection does work for this? Is there a documentation available?
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.