From 3a6408ec67c25f609616c5ef4968664ac7fa1cdf Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Wed, 28 Feb 2024 15:43:15 +0000 Subject: [PATCH 01/11] Main --- readme.md | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index bc84c31..239c654 100644 --- a/readme.md +++ b/readme.md @@ -1,17 +1,42 @@ -# Description of version 1.0.0 +*This repository is part of the outcomes of the Specialist Task Force 620 focusing on the authoring of a World Representation as part of the ETSI ISG Augmented Reality Framework architecture (https://www.etsi.org/deliver/etsi_gs/ARF/001_099/003/01.01.01_60/gs_ARF003v010101p.pdf).* +*The set of the World Representation authoring components includes:* -This project should be used to construct a complete ASP-Net REST server compliant to the ARF World Storage API. It uses auto-generated ASP.NET server code. We propose to use the open source OpenAPI-Generator for this. +*• The C++ and C# source code for servers and clients generated from OpenAPI available here (https://forge.etsi.org/rep/arf/arf005)* + +*• A Unity plugin and a Unity editor for authoring and accessing a World Representation hosted on a World Storage server.* + +*All these components are available under the ETSI Labs group “World Storage API Helpers”: https://labs.etsi.org/rep/arf/world-storage-api-helpers* + +*If you wish to contribute to this project or any other projects in the context of the [ETSI ISG Augmented Reality Framework architecture](https://www.etsi.org/committee/1420-arf), please refer to the ["How to get involved in an ISG" section on the ETSI website](https://www.etsi.org/how-to-get-involved-in-an-isg)* + +--- + +# Description + +This repo should be used to construct a complete ASP-Net REST server compliant to the ARF World Storage API. It uses auto-generated ASP.NET server code. We propose to use the open source OpenAPI-Generator for this. It includes description and code for a fully functional server with MongoDB integration. -# Prerequisites +## Repo Content + +| | File / Folder | Description | +|:-:|:--------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| 📂 | server | The folder where the library code will be generated, the openapi generator is set to not overwrite some files used to generate and initialiue the ASP.Net server system | +| 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | +| 📂 | server/src/Org.OpenAPITools | This is the location where the ASP.Net code will be generated | +| 📂 | server/src/Org.OpenAPITools/ControllersImpl | THis folder contains the code implementating the REST end-paths for the different objects in API | +| 📂 | server/src/Org.OpenAPITools/Services | This folder contains MongoDB database settings and access methods for each API | +| 📂 | arf005 | A submodule pointing to the git containing the API specification file | + +## Requirements + What you need: 1. Installed npm: https://phoenixnap.com/kb/install-node-js-npm-on-windows 2. Installed openapi generator with npm: https://openapi-generator.tech/docs/installation/ 3. Installed docker (if you want to use it): https://www.docker.com/get-started -# Generate or update the server +# Code Generation We provided the file `.openapi-generator-ignore` in `server`, which prevents openapi-generator to override some adapted files. @@ -23,13 +48,13 @@ Open a command shell and execute: Open the solution `Org.OpenAPITools.sln` (folder `server`) in Visual Studio: -## In Visual Studio: +## In Visual Studio Open `NuGet Package Manager` and add `MongoDB.Driver`. -### File adaptations: +### File adaptations Change version number in all files if a new version is provided. -### In the folder `Controllers`: +### In the folder `Controllers` Change "`public class`" to "`public abstract class`". Compare files folder in "`ControllersImpl`" with the corresponding files in "`Controllers`" and adapt if necessary. @@ -38,7 +63,7 @@ Methods should be the same with "`override`" instead of "`virtual`". --- -#### - if files are missing (and only then): +#### If some files are missing (and only then!) Copy them from folder `Controllers`, rename them (append `Impl`) and handle them like the already existing files, i.e.: Change classnames by appending `Impl` to the original classnames (and change filenames accordingly) and inherit from original class in `Controllers` (instead of `ControllerBase`) @@ -58,7 +83,7 @@ Remove sample code and replace it by using the appropriate methods of the corres --- -### In the folder `Models`: +### In the folder `Models` Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) : ``` using MongoDB.Bson; @@ -99,7 +124,7 @@ open a command shell and generate docker by executing in `server/src/Org.OpenAPI docker build -t org.openapitools . ``` -## How to start: +## How to start The easiest way is to use docker-compose: Open a command shell and use docker-compose (if necessary adapt docker-compose.yml) by executing in `server/src/Org.OpenAPITools`: @@ -109,7 +134,7 @@ Open a command shell and use docker-compose (if necessary adapt docker-compose.y Open http://localhost:8080/openapi/index.html in a web-browser, if you want to check the functionalities using SwaggerUI -## How to stop: +## How to stop Open a command shell by executing in `server/src/Org.OpenAPITools`: ``` docker-compose down @@ -121,8 +146,8 @@ Execute the following command in docker: mongodump --db **insert database_name** --out /data-dump/`date +"%Y-%m-%d"` ``` -## How to import database: +## How to import database Execute the following command in docker: ``` mongorestore --db **insert database_name** **insert path_to_bson_file** -``` \ No newline at end of file +``` -- GitLab From e2d05c36f9dd8f2f7fdb00f30252777584c96c83 Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Wed, 28 Feb 2024 19:04:53 +0100 Subject: [PATCH 02/11] New API generated code using abstract class instead of virtual. New folder for all custom classes. batch file to quickly start the creation of the docker and docker-compose. --- .gitignore | 12 +- .gitmodules | 5 +- ...erator-ignore => .openapi-generator-ignore | 20 +- arf005 | 1 - build-iis-docker-ws.bat | 2 + docker-compose.bat | 1 + docker-compose.yml | 45 +++ openapi | 1 + readme.md | 81 ++-- .../worldanalysis/.openapi-generator-ignore | 23 ++ server/worldanalysis/README.md | 50 +++ .../ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore | 362 ++++++++++++++++++ .../ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile | 32 ++ .../ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs | 33 ++ .../ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs | 144 +++++++ .../appsettings.Development.json | 9 + .../appsettings.json | 8 + server/worldstorage/.openapi-generator-ignore | 41 ++ .../ETSI.ARF.OpenAPI.WorldStorage/Dockerfile | 32 ++ .../ETSI-ARF/Services/BaseService.cs | 214 +++++++++++ .../ETSI-ARF/Services/DatabaseSettings.cs | 31 ++ .../ETSI.ARF.OpenAPI.WorldStorage/Program.cs | 35 ++ .../ETSI.ARF.OpenAPI.WorldStorage/Startup.cs | 194 ++++++++++ .../_appsettings.json | 8 + .../appsettings.Development.json | 9 + .../appsettings.json | 18 + 26 files changed, 1357 insertions(+), 54 deletions(-) rename server/.openapi-generator-ignore => .openapi-generator-ignore (84%) delete mode 160000 arf005 create mode 100644 build-iis-docker-ws.bat create mode 100644 docker-compose.bat create mode 100644 docker-compose.yml create mode 160000 openapi create mode 100644 server/worldanalysis/.openapi-generator-ignore create mode 100644 server/worldanalysis/README.md create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json create mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json create mode 100644 server/worldstorage/.openapi-generator-ignore create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json diff --git a/.gitignore b/.gitignore index 1ade888..4507e2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ## Ignore .openapi-generator Folder ## .openapi-generator/ -server/src/Org.OpenAPITools/.gitignore +server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/.gitignore # Visual Studio cache/options directory .vs/ @@ -9,6 +9,9 @@ server/src/Org.OpenAPITools/.gitignore # Visual Studio solution *.sln +# generated project-files +*.csproj + # build-jobs build.* @@ -22,7 +25,7 @@ server/programs/MongoDB/ !server/programs/MongoDB/readme.md #generated readme -server/README.md +server/worldstorage/README.md # all generated directories Attributes/ @@ -36,11 +39,8 @@ OpenAPI/ Properties/ wwwroot/ -# generated project-files -*.csproj - # generated Program.cs -Program.cs +#Program.cs # backup-files *.bak diff --git a/.gitmodules b/.gitmodules index 120fcda..54f9b63 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,7 @@ [submodule "arf005"] path = arf005 url = git@forge.etsi.org:arf/arf005.git - branch = develop \ No newline at end of file + branch = develop +[submodule "openapi"] + path = openapi + url = https://forge.etsi.org/rep/arf/openapi.git diff --git a/server/.openapi-generator-ignore b/.openapi-generator-ignore similarity index 84% rename from server/.openapi-generator-ignore rename to .openapi-generator-ignore index cbd23cf..38a29ad 100644 --- a/server/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -22,16 +22,20 @@ # Then explicitly reverse the ignore rule for a single file: #!docs/README.md +# +# ETSI - ISG - ARF +# +**\ETSI.ARF.OpenAPI.WorldStorage.csproj +# Modules to initialize World Storage database, server.... +**/Program.cs **/Startup.cs -**/appsettings.json **/Dockerfile -**/docker-compose.yml -**/.openapi-generator-ignore - +**/appsettings.json -# ARF # Implementation of REST request and database functionalities -# -**/ControllersImpl -**/Services +**/ETSI-ARF + +# Design of some web pages +**/wwwroot/portal +**/wwwroot/index.html \ No newline at end of file diff --git a/arf005 b/arf005 deleted file mode 160000 index 533b9d3..0000000 --- a/arf005 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 533b9d3198b772c7b628b0ab0e0a144b89966b46 diff --git a/build-iis-docker-ws.bat b/build-iis-docker-ws.bat new file mode 100644 index 0000000..ef7ec22 --- /dev/null +++ b/build-iis-docker-ws.bat @@ -0,0 +1,2 @@ +cd server\worldstorage\src\ETSI.ARF.OpenAPI.WorldStorage +docker build -t etsi.arf.openapi.worldstorage . \ No newline at end of file diff --git a/docker-compose.bat b/docker-compose.bat new file mode 100644 index 0000000..81eda89 --- /dev/null +++ b/docker-compose.bat @@ -0,0 +1 @@ +docker-compose up -d --force-recreate --remove-orphans \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0f23eca --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +# Please refer https://aka.ms/HTTPSinContainer on how to setup an https developer certificate for your ASP .NET Core service. + +name: etsi_arf_server +version: '1.0' + +networks: + minionetwork: + driver: bridge + vpcbr: + ipam: + config: + - subnet: 172.24.30.0/24 + +services: + mongod: + container_name: etsi_mongodb + image: mongo:latest + environment: + - PUID=1000 + - PGID=1000 + volumes: + # - mongodbdata:/data/mongodb:rw + - C:/Fraunhofer/Servers/ETSI/MongoDB/data:/data/db:rw + - C:/Fraunhofer/Servers/ETSI/MongoDB/data-dump:/data/db-dump:rw + # - D:/Fraunhofer/Servers/ETSI/MongoDB/mongod.yaml:/etc/mongod.conf:rw + ports: + - 27037:27017 + - 27038:27018 + networks: + vpcbr: + ipv4_address: 172.24.30.101 + restart: unless-stopped + + etsiapi: + container_name: etsi_arf_iis_server + image: etsi.arf.openapi.worldstorage:latest + volumes: + - C:/Fraunhofer/Servers/ETSI/appsettings.json:/app/appsettings.json:rw + - C:/Fraunhofer/Servers/ETSI/WWWRoot:/app/wwwroot:rw + ports: + - 8082:44301 + networks: + vpcbr: + ipv4_address: 172.24.30.100 + restart: unless-stopped diff --git a/openapi b/openapi new file mode 160000 index 0000000..08aa3ca --- /dev/null +++ b/openapi @@ -0,0 +1 @@ +Subproject commit 08aa3ca82b2f3d78ee765df3e0d9046b3ab81ba1 diff --git a/readme.md b/readme.md index 239c654..7715c17 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ --- -# Description +# Description - Version for STF 669 This repo should be used to construct a complete ASP-Net REST server compliant to the ARF World Storage API. It uses auto-generated ASP.NET server code. We propose to use the open source OpenAPI-Generator for this. @@ -34,7 +34,7 @@ What you need: 1. Installed npm: https://phoenixnap.com/kb/install-node-js-npm-on-windows 2. Installed openapi generator with npm: https://openapi-generator.tech/docs/installation/ -3. Installed docker (if you want to use it): https://www.docker.com/get-started +3. Installed docker (recommanded): https://www.docker.com/get-started # Code Generation @@ -43,10 +43,10 @@ We provided the file `.openapi-generator-ignore` in `server`, which prevents ope ## Auto-generate server code Open a command shell and execute: ``` - openapi-generator-cli generate -i arf005\API\openapi.yaml -g aspnetcore -o server + npx openapi-generator-cli generate -i openapi/API/worldstorage/worldstorageopenapi.yaml --additional-properties aspnetCoreVersion=5.0,packageName=ETSI.ARF.OpenAPI.WorldStorage,operationModifier=abstract,classModifier=abstract -g aspnetcore -o server/worldstorage ``` -Open the solution `Org.OpenAPITools.sln` (folder `server`) in Visual Studio: +Open the solution `ETSI.ARF.OpenAPI.WorldStorage.sln` (folder `server/worldstorage`) in Visual Studio: ## In Visual Studio Open `NuGet Package Manager` and add `MongoDB.Driver`. @@ -54,37 +54,41 @@ Open `NuGet Package Manager` and add `MongoDB.Driver`. ### File adaptations Change version number in all files if a new version is provided. -### In the folder `Controllers` -Change "`public class`" to "`public abstract class`". +### Implementation folder (new) +All custom files are now in the folder 'ETSI-ARF'. Nothing to do adapt manually after generation. But you have to provide the implementation of new endpoints because they are now directly declared as abstract (default). -Compare files folder in "`ControllersImpl`" with the corresponding files in "`Controllers`" and adapt if necessary. +The folder contains following subfolders: +`Controllers` -Methods should be the same with "`override`" instead of "`virtual`". +Compare files folder in "`ETSI-ARF/Controllers`" with the corresponding files in "`Controllers`" and insert if necessary the new methods. + +Methods should be the same with "`override`" instead of "`abstract`". --- #### If some files are missing (and only then!) -Copy them from folder `Controllers`, rename them (append `Impl`) and handle them like the already existing files, i.e.: -Change classnames by appending `Impl` to the original classnames (and change filenames accordingly) and inherit from original class in `Controllers` (instead of `ControllerBase`) - -..and replace `virtual` by `override` with all methods. - Add ``` - using Org.OpenAPITools.Services; using MongoDB.Driver; ``` -Add a private readonly service class variable like in the already existing files. +Add a private readonly service class variable like in the already existing files, e.g.: +``` +private readonly TrackableService _trackableService; +``` Add a constructor with this service class variable like in the already existing files. +``` +public TrackablesApiControllerImpl(TrackableService trackableService) +{ + _trackableService = trackableService; +} +``` -Remove sample code and replace it by using the appropriate methods of the corresponding classes in the folder `Services` (which you may be have to create). - ---- +Implement endpoint code using the appropriate MogoDB methods of the corresponding classes from the folder `Services` (which you may be have to create). ### In the folder `Models` -Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) : +Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) inherited from `IModels` (definition of the extra UUID): ``` using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; @@ -109,6 +113,17 @@ If you don't have a MongoDB, follow the instructions in `readme.md` in `server/p ...and put MongoDB in folder `server/programs/MongoDB` (download MongoDB as zip-file from https://www.mongodb.com/try/download/community and unzip the file into this directory, so that the bin-directory is in this folder). +## How to dump database +Execute the following command in docker: +``` + mongodump --db **insert database_name** --out /data-dump/`date +"%Y-%m-%d"` +``` + +## How to import database +Execute the following command in docker: +``` + mongorestore --db **insert database_name** **insert path_to_bson_file** +``` # Use in Visual Studio Make sure, that an instance of MongoDB is running. @@ -116,38 +131,28 @@ Make sure, that an instance of MongoDB is running. Start application with IIS Express. -# Use within a Docker +# Use API within a Docker + +## Creating the IIS docker ## Remove the substring `src/Org.OpenAPITools/` in Dockerfile (if not already done) -open a command shell and generate docker by executing in `server/src/Org.OpenAPITools`: +open a command shell and generate docker by executing: ``` - docker build -t org.openapitools . + build-iis-docker-ws.bat ``` -## How to start +## How to start (with Docker-Compose) The easiest way is to use docker-compose: -Open a command shell and use docker-compose (if necessary adapt docker-compose.yml) by executing in `server/src/Org.OpenAPITools`: +Open a command shell and use docker-compose (if necessary adapt docker-compose.yml) by executing`: ``` - docker-compose up --force-recreate --remove-orphan --detach + docker-compose.bat ``` Open http://localhost:8080/openapi/index.html in a web-browser, if you want to check the functionalities using SwaggerUI ## How to stop -Open a command shell by executing in `server/src/Org.OpenAPITools`: +Open a command shell by executing in `server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage`: ``` docker-compose down ``` - -## How to dump database -Execute the following command in docker: -``` - mongodump --db **insert database_name** --out /data-dump/`date +"%Y-%m-%d"` -``` - -## How to import database -Execute the following command in docker: -``` - mongorestore --db **insert database_name** **insert path_to_bson_file** -``` diff --git a/server/worldanalysis/.openapi-generator-ignore b/server/worldanalysis/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/server/worldanalysis/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/server/worldanalysis/README.md b/server/worldanalysis/README.md new file mode 100644 index 0000000..ac3ce3d --- /dev/null +++ b/server/worldanalysis/README.md @@ -0,0 +1,50 @@ +# ETSI.ARF.OpenAPI.WorldAnalysis - ASP.NET Core 5.0 Server + +API ensuring interoperability between Scene Management and a World Analysis service + +## Upgrade NuGet Packages + +NuGet packages get frequently updated. + +To upgrade this solution to the latest version of all NuGet packages, use the dotnet-outdated tool. + + +Install dotnet-outdated tool: + +``` +dotnet tool install --global dotnet-outdated-tool +``` + +Upgrade only to new minor versions of packages + +``` +dotnet outdated --upgrade --version-lock Major +``` + +Upgrade to all new versions of packages (more likely to include breaking API changes) + +``` +dotnet outdated --upgrade +``` + + +## Run + +Linux/OS X: + +``` +sh build.sh +``` + +Windows: + +``` +build.bat +``` +## Run in Docker + +``` +cd src/ETSI.ARF.OpenAPI.WorldAnalysis +docker build -t etsi.arf.openapi.worldanalysis . +docker run -p 5000:8080 etsi.arf.openapi.worldanalysis +``` diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore new file mode 100644 index 0000000..1ee5385 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore @@ -0,0 +1,362 @@ +## 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 + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 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 +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +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 +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# 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.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +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/ + +# 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 ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile new file mode 100644 index 0000000..1203a89 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile @@ -0,0 +1,32 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +# Container we use for final publish +FROM mcr.microsoft.com/dotnet/core/aspnet:5.0-buster-slim AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +# Build container +FROM mcr.microsoft.com/dotnet/core/sdk:5.0-buster AS build + +# Copy the code into the container +WORKDIR /src +COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj", "ETSI.ARF.OpenAPI.WorldAnalysis/"] + +# NuGet restore +RUN dotnet restore "ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj" +COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/", "ETSI.ARF.OpenAPI.WorldAnalysis/"] + +# Build the API +WORKDIR "ETSI.ARF.OpenAPI.WorldAnalysis" +RUN dotnet build "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/build + +# Publish it +FROM build AS publish +RUN dotnet publish "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/publish + +# Make the final image for publishing +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ETSI.ARF.OpenAPI.WorldAnalysis.dll"] diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs new file mode 100644 index 0000000..95e2206 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + /// + /// Program + /// + public class Program + { + /// + /// Main + /// + /// + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + /// + /// Create the host builder. + /// + /// + /// IHostBuilder + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup() + .UseUrls("http://0.0.0.0:8080/"); + }); + } +} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs new file mode 100644 index 0000000..eca5631 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs @@ -0,0 +1,144 @@ +/* + * World Analysis API + * + * API ensuring interoperability between Scene Management and a World Analysis service + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.IO; +using System.Reflection; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using ETSI.ARF.OpenAPI.WorldAnalysis.Authentication; +using ETSI.ARF.OpenAPI.WorldAnalysis.Filters; +using ETSI.ARF.OpenAPI.WorldAnalysis.OpenApi; +using ETSI.ARF.OpenAPI.WorldAnalysis.Formatters; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + /// + /// Startup + /// + public class Startup + { + /// + /// Constructor + /// + /// + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + /// + /// The application configuration. + /// + public IConfiguration Configuration { get; } + + /// + /// This method gets called by the runtime. Use this method to add services to the container. + /// + /// + public void ConfigureServices(IServiceCollection services) + { + + // Add framework services. + services + // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ + .AddControllers(options => { + options.InputFormatters.Insert(0, new InputFormatterStream()); + }) + .AddNewtonsoftJson(opts => + { + opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + opts.SerializerSettings.Converters.Add(new StringEnumConverter + { + NamingStrategy = new CamelCaseNamingStrategy() + }); + }); + services + .AddSwaggerGen(c => + { + c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); + + c.SwaggerDoc("1.0.0", new OpenApiInfo + { + Title = "World Analysis API", + Description = "World Analysis API (ASP.NET Core 5.0)", + TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"), + Contact = new OpenApiContact + { + Name = "OpenAPI-Generator Contributors", + Url = new Uri("https://github.com/openapitools/openapi-generator"), + Email = "" + }, + License = new OpenApiLicense + { + Name = "NoLicense", + Url = new Uri("https://opensource.org/licenses/BSD-3-Clause") + }, + Version = "1.0.0", + }); + c.CustomSchemaIds(type => type.FriendlyId(true)); + c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml"); + + // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..) + // Use [ValidateModelState] on Actions to actually validate it in C# as well! + c.OperationFilter(); + }); + services + .AddSwaggerGenNewtonsoftSupport(); + } + + /// + /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + /// + /// + /// + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseDefaultFiles(); + app.UseStaticFiles(); + app.UseSwagger(c => + { + c.RouteTemplate = "openapi/{documentName}/openapi.json"; + }) + .UseSwaggerUI(c => + { + // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html + c.RoutePrefix = "openapi"; + //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes) + c.SwaggerEndpoint("/openapi/1.0.0/openapi.json", "World Analysis API"); + + //TODO: Or alternatively use the original OpenAPI contract that's included in the static files + // c.SwaggerEndpoint("/openapi-original.json", "World Analysis API Original"); + }); + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json new file mode 100644 index 0000000..e203e94 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json new file mode 100644 index 0000000..def9159 --- /dev/null +++ b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/server/worldstorage/.openapi-generator-ignore b/server/worldstorage/.openapi-generator-ignore new file mode 100644 index 0000000..38a29ad --- /dev/null +++ b/server/worldstorage/.openapi-generator-ignore @@ -0,0 +1,41 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md + +# +# ETSI - ISG - ARF +# +**\ETSI.ARF.OpenAPI.WorldStorage.csproj + +# Modules to initialize World Storage database, server.... +**/Program.cs +**/Startup.cs +**/Dockerfile +**/appsettings.json + +# Implementation of REST request and database functionalities +**/ETSI-ARF + +# Design of some web pages +**/wwwroot/portal +**/wwwroot/index.html \ No newline at end of file diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile new file mode 100644 index 0000000..1d802b3 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Dockerfile @@ -0,0 +1,32 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +# Container we use for final publish +FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +# Build container +FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build + +# Copy the code into the container +WORKDIR /src +COPY ["ETSI.ARF.OpenAPI.WorldStorage.csproj", "ETSI.ARF.OpenAPI.WorldStorage/"] + +# NuGet restore +RUN dotnet restore "ETSI.ARF.OpenAPI.WorldStorage/ETSI.ARF.OpenAPI.WorldStorage.csproj" +COPY [".", "ETSI.ARF.OpenAPI.WorldStorage/"] + +# Build the API +WORKDIR "ETSI.ARF.OpenAPI.WorldStorage" +RUN dotnet build "ETSI.ARF.OpenAPI.WorldStorage.csproj" -c Release -o /app/build + +# Publish it +FROM build AS publish +RUN dotnet publish "ETSI.ARF.OpenAPI.WorldStorage.csproj" -c Release -o /app/publish + +# Make the final image for publishing +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ETSI.ARF.OpenAPI.WorldStorage.dll"] diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs new file mode 100644 index 0000000..2e1e8cd --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Net.NetworkInformation; + +using MongoDB.Driver; +using MongoDB.Bson; +using MongoDB.Bson.Serialization; +using MongoDB.Bson.Serialization.Serializers; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using Microsoft.AspNetCore.Mvc; + + +#pragma warning disable CS1591 // Fehlendes XML-Kommentar für öffentlich sichtbaren Typ oder Element +namespace ETSI.ARF.OpenAPI.WorldStorage.Services +{ + abstract public class BaseService + { + // The object is created by first access? so the singleton may be null if nothing here was called before + static public BaseService Singleton => _singleton; + static protected BaseService _singleton = null; + + public IDatabaseSettings Settings => _settings; + protected IDatabaseSettings _settings; + + protected string mongoServer; + protected MongoClient mongoClient; + protected IMongoDatabase mongoDatabase; + protected IMongoCollection mongoCollection; + + public BaseService(IDatabaseSettings settings) + { + // Store the singleton + if (_singleton != null) throw new Exception("Service can only be instantiated one time!"); + else _singleton = this; + + _settings = settings; + + // Open the mongo database + //BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)); + mongoServer = SelectMongoServer(settings); + mongoClient = new MongoClient(mongoServer); + mongoDatabase = mongoClient.GetDatabase(settings.DatabaseName); + } + + ~BaseService() + { + // to do? + } + + // Check manually if a GUID document already exists! + public bool CheckIfExist(Guid GUID) + { + foreach (var obj in Get()) + { + if (((Models.IModels)obj).GUID == GUID) return true; + } + return false; + } + + public long NumOfDocuments() + { + if (mongoCollection == null) return -1; + else return mongoCollection.CountDocuments(new BsonDocument()); + } + + private void _print(T obj) + { + Console.WriteLine("[Mongo Server] User # " + ((Models.IModels)obj).GUID); + } + + public void PrintAll() + { + // Execute a _print to all elements + var a = mongoCollection.Find(_ => true); + a.ForEachAsync(_print).Wait(); + } + + public T Create(T obj) + { + // Test first if GUID doesn't exist + bool exist = CheckIfExist(((Models.IModels)obj).GUID); + if (!exist) + { + mongoCollection.InsertOne(obj); + return obj; + } + else return default(T); + } + + // + // Get the current mongo _id of the object in the database + // + #region Get current mongo ID or object/document + private Guid _newObjGUID; + private T _currentObj; + private ObjectId _currentMongoID; + private ObjectId getMongoIDFromName(string name) + { + var res = mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault(); + if (res == null) return ObjectId.Empty; + else return ((Models.IModels)res)._mongoID; + } + + private ObjectId getMongoIDFromGUID(Guid GUID) + { + _newObjGUID = GUID; + _currentMongoID = ObjectId.Empty; + var i = mongoCollection.Find(_ => true); + i.ForEachAsync(_compareAndRemember).Wait(); + return _currentMongoID; + } + + private void _compareAndRemember(T obj) + { + if (_currentMongoID != ObjectId.Empty) return; // take the first one + if (((Models.IModels)obj).GUID == _newObjGUID) + { + _currentObj = obj; + _currentMongoID = ((Models.IModels)obj)._mongoID; + } + } + #endregion + + //abstract public long Replace(T obj); + public long Replace(T obj) //=> assetCollection.ReplaceOne(asset => asset.GUID == GUID, obj); + { + // Which mongo document? + ObjectId mongoID = getMongoIDFromGUID(((Models.IModels)obj).GUID); + + // Object was found, so replace it using the _id + if (mongoID != ObjectId.Empty) + { + ((Models.IModels)obj)._mongoID = mongoID; + return mongoCollection.ReplaceOne(o => ((Models.IModels)o)._mongoID == mongoID, obj).MatchedCount; + } + else return 0; + } + + public long Remove(T obj) => Remove(((Models.IModels)obj).GUID); + + public long Remove(Guid GUID) + { + //return mongoCollection.DeleteOne(o => ((Models.IModels)o).GUID == GUID); + + // Which mongo document? + ObjectId mongoID = getMongoIDFromGUID(GUID); + + // Object was found, so replace it using the _id + if (mongoID != ObjectId.Empty) + { + // todo: check if the user is allowed to delete the object! + + return mongoCollection.DeleteOne(o => ((Models.IModels)o)._mongoID == mongoID).DeletedCount; + } + else return 0; + } + + // Return all documents + public List Get() => mongoCollection.Find(_ => true).ToList(); + + // Limit the result to the first n documents + public List Get(int limit) => mongoCollection.Find(_ => true).Limit(limit).ToList(); + + // Search manually the document with the id GUID + public T Get(string name) => mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault(); + + // Geht nicht! public override T Get(Guid GUID) => mongoCollection.Find(o => o.GUID == GUID).FirstOrDefault(); + // Work around: look in all elements if the GUIDs are equals + public T Get(Guid GUID) + { + foreach (T obj in Get()) + { + if (((Models.IModels)obj).GUID == GUID) return obj; + } + return default(T); + } + + // + // Select the server or use a local database + // + private string SelectMongoServer(IDatabaseSettings settings) + { + string server = null; + Ping myPing = new Ping(); + try + { + PingReply reply = myPing.Send(settings.MongoSrv, 1000); + if (reply != null) + { + server = settings.MongoSrv; + Console.WriteLine("[Mongo Server] Status: " + reply.Status + " \n Time: " + reply.RoundtripTime.ToString() + " \n Address: " + reply.Address); + } + } + catch (PingException e) + { + server = null; + Console.WriteLine("[Mongo Server] Ping: " + e.ToString()); + } + + if (server is null) + { + // Use the local mongo server + server = "localhost"; + Console.WriteLine("[Mongo Server] Take localhost"); + } + server = "mongodb://" + server + ":" + settings.MongoPort + "/"; + mongoServer = server; + return server; + } + } +} +#pragma warning restore CS1591 // Fehlendes XML-Kommentar für öffentlich sichtbaren Typ oder Element diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs new file mode 100644 index 0000000..197907f --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +#pragma warning disable CS1591 +namespace ETSI.ARF.OpenAPI.WorldStorage.Services +{ + public interface IDatabaseSettings + { + string LocalDataPath { get; set; } + string DatabaseName { get; set; } + string MongoSrv { get; set; } + string MongoPort { get; set; } + public string CollectionNameWorldLink { get; set; } + public string CollectionNameTrackables { get; set; } + public string CollectionNameWorldAnchor { get; set; } + } + + public class DatabaseSettings : IDatabaseSettings + { + public string LocalDataPath { get; set; } + public string DatabaseName { get; set; } + public string MongoSrv { get; set; } + public string MongoPort { get; set; } + public string CollectionNameWorldLink { get; set; } + public string CollectionNameTrackables { get; set; } + public string CollectionNameWorldAnchor { get; set; } + } +} +#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs new file mode 100644 index 0000000..a99fc84 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using System; + +namespace ETSI.ARF.OpenAPI.WorldStorage +{ + /// + /// Program + /// + public class Program + { + /// + /// Main + /// + /// + public static void Main(string[] args) + { + Console.WriteLine("ETSI ARF ASP.Net server started."); + CreateHostBuilder(args).Build().Run(); + } + + /// + /// Create the host builder. + /// + /// + /// IHostBuilder + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup() + .UseUrls("http://0.0.0.0:44301/"); // SylR: Wichtig!!! + }); + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs new file mode 100644 index 0000000..a6299c1 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs @@ -0,0 +1,194 @@ +/* + * World Storage API + * + * API ensuring interoperability between an authoring tool and a World Storage service + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.IO; +using System.Reflection; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using ETSI.ARF.OpenAPI.WorldStorage.Authentication; +using ETSI.ARF.OpenAPI.WorldStorage.Filters; +using ETSI.ARF.OpenAPI.WorldStorage.OpenApi; +using ETSI.ARF.OpenAPI.WorldStorage.Formatters; +using ETSI.ARF.OpenAPI.WorldStorage.Services; +using MongoDB.Bson.Serialization.Serializers; +using MongoDB.Bson.Serialization; +using MongoDB.Bson; +using Microsoft.Extensions.Options; + +namespace ETSI.ARF.OpenAPI.WorldStorage +{ + /// + /// Startup + /// + public class Startup + { + // + // SylR, Fraunhofer HHI + // + /// + /// The API version. (how to read it from the yaml?) + /// + static public string apiVersion = "1.0.0"; + + /// + /// Demo access key + /// + static public string accessKey = "My!Key.ETSI"; + + /// + /// Demo secret key + /// + static public string secretKey = "GW0Wae1t4Cs5rAqEbPYFWO9J5nSbpJXxp1F3uv0J"; + + /// + /// Constructor + /// + /// + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + /// + /// The application configuration. + /// + public IConfiguration Configuration { get; } + + /// + /// SylR: Check if the request is authorized + /// + /// + /// + //static public bool IsAccessAllowed(ETSI.ARF.OpenAPI.WorldStorage.Models.SecureAccess security) + //{ + // Console.WriteLine(security.AccessKey); + // return true; + // //return (security.AccessKey == accessKey && security.SecretKey == secretKey); + //} + + /// + /// This method gets called by the runtime. Use this method to add services to the container. + /// + /// + public void ConfigureServices(IServiceCollection services) + { + // + // SylR, Fraunhofer HHI + // + + // appsetting.json - requires using Microsoft.Extensions.Options + services.Configure(Configuration.GetSection(nameof(DatabaseSettings))); + + // + // MongoDB + // + BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)); + //BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; + var s = services.AddSingleton(sp => sp.GetRequiredService>().Value); + //services.AddSingleton(); + //services.AddSingleton(); + + // Add framework services. + services + // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ + .AddControllers(options => { + options.InputFormatters.Insert(0, new InputFormatterStream()); + }) + .AddNewtonsoftJson(opts => + { + opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + opts.SerializerSettings.Converters.Add(new StringEnumConverter + { + NamingStrategy = new CamelCaseNamingStrategy() + }); + }); + services + .AddSwaggerGen(c => + { + c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); + + c.SwaggerDoc(apiVersion, new OpenApiInfo + { + Title = "World Storage API", + Description = "World Storage API (ASP.NET Core 5.0)", + TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"), + Contact = new OpenApiContact + { + Name = "OpenAPI-Generator Contributors", + Url = new Uri("https://github.com/openapitools/openapi-generator"), + Email = "" + }, + License = new OpenApiLicense + { + Name = "NoLicense", + Url = new Uri("https://opensource.org/licenses/BSD-3-Clause") + }, + Version = apiVersion, + }); + c.CustomSchemaIds(type => type.FriendlyId(true)); + c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml"); + + // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..) + // Use [ValidateModelState] on Actions to actually validate it in C# as well! + c.OperationFilter(); + }); + services + .AddSwaggerGenNewtonsoftSupport(); + } + + /// + /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + /// + /// + /// + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseDefaultFiles(); + app.UseStaticFiles(); + app.UseSwagger(c => + { + c.RouteTemplate = "openapi/{documentName}/openapi.json"; + }) + .UseSwaggerUI(c => + { + // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html + c.RoutePrefix = "openapi"; + //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes) + //c.SwaggerEndpoint("/openapi/" + apiVersion + "/openapi.json", "World Storage API"); + + //TODO: Or alternatively use the original OpenAPI contract that's included in the static files + c.SwaggerEndpoint("/openapi-original.json", "World Storage API Original"); + }); + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json new file mode 100644 index 0000000..def9159 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json new file mode 100644 index 0000000..e203e94 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json new file mode 100644 index 0000000..7b6341f --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json @@ -0,0 +1,18 @@ +{ + "DatabaseSettings": { + "Description" : "Version for IIS", + "LocalDataPath": ".\\wwwroot\\dataspace\\data", + "MongoSrv": "localhost", + "MongoPort": "27017", + "DatabaseName": "WorldStorageAPI", + "CollectionNameWorldLink": "WorldLink", + "CollectionNameTrackables": "Trackables", + "CollectionNameWorldAnchor": "WorldAnchor" + }, + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} -- GitLab From bfcffe4f4238dfae6835d4a49d0df7dc1d4a3c28 Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Wed, 28 Feb 2024 19:23:25 +0100 Subject: [PATCH 03/11] Now all... --- .../ETSI-ARF/Controllers/DefaultApiExt.cs | 153 ++++++++++++++++++ .../ETSI-ARF/Models/IModels.cs | 39 +++++ 2 files changed, 192 insertions(+) create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs new file mode 100644 index 0000000..6c48dcd --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs @@ -0,0 +1,153 @@ +/* + * SmartSite Core System API + * + * API ensuring interoperability between the various services, tools and apps in SmartSite + * + * The version of the OpenAPI document: 1.0.2 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.Net; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Swashbuckle.AspNetCore.Annotations; +using Swashbuckle.AspNetCore.SwaggerGen; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Attributes; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using ETSI.ARF.OpenAPI.WorldStorage.Services; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers +{ +#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element + /// + /// + /// + public class DefaultApiControllerExt : DefaultApiController + { + public override IActionResult GetPing() + { + string answer = "Pong"; + return new ObjectResult(answer); + } + + public override IActionResult GetAdmin() + { + string answer = "ETSI ARF Server Running."; + return new ObjectResult(answer); + } + + public override IActionResult GetVersion() + { + string answer = "ETSI ARF RESTful API 1.0.1"; + return new ObjectResult(answer); + } + + [NonAction] + private string writeMsg(string title, string msg) + { + return $"

{title}: \t {msg}

"; + } + + [NonAction] + public /*override*/ IActionResult GetReport() + { + string projectName = "ETSI ARF - STF 620"; + string machinename = System.Environment.MachineName; + string hostname = Dns.GetHostName(); + var ips = Dns.GetHostAddresses(hostname); + + string status = "Running"; + string mongoStatus = "Running"; + //string mongoCollectionUsers = "Number = " + UserService.Singleton?.NumOfDocuments(); + //string mongoCollectionMachines = "Number = " + MachineService.Singleton?.NumOfDocuments(); + //string mongoCollectionAssets = "Number = " + AssetService.Singleton?.NumOfDocuments(); + //string mongoCollectionJobs = "Number = " + JobService.Singleton?.NumOfDocuments(); + + //List users = UserService.Singleton?.Get(); + //int activeU = 0; + //int nonActiveU = 0; + //foreach (var u in users) + // if (u.IsLogged) activeU++; + // else nonActiveU++; + + //List jobs = JobService.Singleton?.Get(); + //int jobNum = 0; + //foreach (var j in jobs) + // if (j.Progress != 100) jobNum++; + + // + // Simple output + // + string html = " " + + "" + + " SmartSiteCloud" + + "" + + "" + + "

SmartSite Cloud

" + + "

Server based on IIS/ASP.NET

" + + writeMsg("Local Date & Time:", DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString()) + + writeMsg("Machine Name", machinename) + writeMsg("Host Name", hostname) + writeMsg("IPv6", ips[0].ToString()) + + "

Services

" + + writeMsg("WebServer", status) + + writeMsg("MongoDB", mongoStatus) + + //writeMsg(" > Users", mongoCollectionUsers) + + //writeMsg(" > Machines", mongoCollectionMachines) + + //writeMsg(" > Assets", mongoCollectionAssets) + + //writeMsg(" > Jobs", mongoCollectionJobs) + + "

Database

" + + //"

Users

" + + // writeMsg(" - Active", activeU.ToString()) + + // writeMsg(" - Non active", nonActiveU.ToString()) + + //"

Jobs

" + + // writeMsg(" - Running jobs", jobNum.ToString()) + + " "; + + // + // Complex output (for RocketCake) + // + // always use https + //string domainName = (HttpContext.Request.IsHttps ? "https://" : "https://") + HttpContext.Request.Host.ToUriComponent() + "/portal"; // Ex: "https://localhost:44301/portal" + //string root = Path.Combine(Startup.wPath, "portal"); + //string htmlFname = Path.Combine(root, "status.html"); + //string[] template = System.IO.File.ReadAllLines(htmlFname); + //string html2 = ""; + + //string msg1 = + // writeMsg("Domain", domainName) + + // writeMsg("Project", projectName) + + // writeMsg("Local Date", DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString()) + + // writeMsg("Machine Name", machinename) + writeMsg("Host Name", hostname) + writeMsg("IPv6", ips[0].ToString()); + //string msg2 = + // writeMsg("WebServer", status) + + // writeMsg("MongoDB", mongoStatus) + + // //writeMsg(" > Users", mongoCollectionUsers) + + // //writeMsg(" > Machines", mongoCollectionMachines) + + // //writeMsg(" > Assets", mongoCollectionAssets) + + // //writeMsg(" > Jobs", mongoCollectionJobs) + + // writeMsg("MinIO", "-"); + + + //foreach (var line in template) + //{ + // string res = line; + // res = res.Replace("src=\"", "src=\"" + domainName + "/"); + // res = res.Replace("href=\"", "href=\"" + domainName + "/"); + // res = res.Replace("$name1$", projectName); + // res = res.Replace("$msg1$", msg1); + // res = res.Replace("$msg2$", msg2); + // html2 += res; + //} + + return Content(html, "text/html"); + //return Content(html2, "text/html"); + } + } +#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs new file mode 100644 index 0000000..c6660a8 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using System.Text; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Converters; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Models +{ + /// + /// Base element representing an object in the MongoDB. + /// + public interface IModels + { + /// + /// Accessor for the ID managed by mongo + /// + public ObjectId _mongoID { get; set; } + + // Not used!!! + // public Metadata Metadata { get; set; } + + /// + /// Name of the object + /// + public string Name { get; set; } + + /// + /// GUID is managed by EConoM system + /// + public Guid GUID { get; set; } + + } +} \ No newline at end of file -- GitLab From a83d4243401dc80614ffaada2477d0c9fd5d16db Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Thu, 29 Feb 2024 17:43:50 +0100 Subject: [PATCH 04/11] New file structures (one subfolder for all custom modules). Implementation as for STF 620. No implementation for new endpoints for world storage. No implementation for world analysis. --- .gitignore | 10 +- readme.md | 39 +- .../ControllersImpl/DefaultApiImpl.cs | 102 ----- .../ControllersImpl/TrackablesApiImpl.cs | 220 ----------- .../ControllersImpl/WorldAnchorsApiImpl.cs | 222 ----------- .../ControllersImpl/WorldLinksApiImpl.cs | 271 ------------- server/src/Org.OpenAPITools/Dockerfile | 32 -- .../Services/TrackableService.cs | 86 ----- .../Services/WorldAnchorService.cs | 83 ---- .../Services/WorldLinkService.cs | 83 ---- server/src/Org.OpenAPITools/Startup.cs | 180 --------- server/src/Org.OpenAPITools/appsettings.json | 15 - .../src/Org.OpenAPITools/docker-compose.yml | 41 -- .../Org.OpenAPITools/docker/appsettings.json | 15 - .../worldanalysis/.openapi-generator-ignore | 23 -- server/worldanalysis/README.md | 50 --- .../ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore | 362 ------------------ .../ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile | 32 -- .../ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs | 33 -- .../ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs | 144 ------- .../appsettings.Development.json | 9 - .../appsettings.json | 8 - .../DefaultImpl.cs} | 4 +- .../ControllersImpl/TrackablesImpl.cs | 158 ++++++++ .../ControllersImpl/WorldAnchorsImpl.cs | 160 ++++++++ .../ControllersImpl/WorldLinksImpl.cs | 207 ++++++++++ .../ETSI-ARF/{Models => ModelsExt}/IModels.cs | 5 +- .../ETSI-ARF/ModelsExt/TrackableExt.cs | 42 ++ .../ETSI-ARF/ModelsExt/WorldAnchorExt.cs | 42 ++ .../ETSI-ARF/ModelsExt/WorldLinksExt.cs | 48 +++ .../ETSI-ARF/Services/BaseService.cs | 64 ++-- .../ETSI-ARF/Services/DatabaseSettings.cs | 8 +- .../ETSI-ARF/Services/TrackableService.cs} | 36 +- .../ETSI-ARF/Services/WorldAnchorService.cs | 44 +++ .../ETSI-ARF/Services/WorldLinkService.cs | 67 ++++ .../ETSI.ARF.OpenAPI.WorldStorage/Startup.cs | 8 +- .../_appsettings.json | 8 - .../appsettings.json | 8 +- 38 files changed, 864 insertions(+), 2105 deletions(-) delete mode 100644 server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs delete mode 100644 server/src/Org.OpenAPITools/ControllersImpl/TrackablesApiImpl.cs delete mode 100644 server/src/Org.OpenAPITools/ControllersImpl/WorldAnchorsApiImpl.cs delete mode 100644 server/src/Org.OpenAPITools/ControllersImpl/WorldLinksApiImpl.cs delete mode 100644 server/src/Org.OpenAPITools/Dockerfile delete mode 100644 server/src/Org.OpenAPITools/Services/TrackableService.cs delete mode 100644 server/src/Org.OpenAPITools/Services/WorldAnchorService.cs delete mode 100644 server/src/Org.OpenAPITools/Services/WorldLinkService.cs delete mode 100644 server/src/Org.OpenAPITools/Startup.cs delete mode 100644 server/src/Org.OpenAPITools/appsettings.json delete mode 100644 server/src/Org.OpenAPITools/docker-compose.yml delete mode 100644 server/src/Org.OpenAPITools/docker/appsettings.json delete mode 100644 server/worldanalysis/.openapi-generator-ignore delete mode 100644 server/worldanalysis/README.md delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json delete mode 100644 server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json rename server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/{Controllers/DefaultApiExt.cs => ControllersImpl/DefaultImpl.cs} (98%) create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs rename server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/{Models => ModelsExt}/IModels.cs (91%) create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/TrackableExt.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldAnchorExt.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldLinksExt.cs rename server/{src/Org.OpenAPITools/Services/DatabaseSettings.cs => worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/TrackableService.cs} (53%) create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldAnchorService.cs create mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldLinkService.cs delete mode 100644 server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json diff --git a/.gitignore b/.gitignore index 4507e2b..45d2095 100644 --- a/.gitignore +++ b/.gitignore @@ -27,17 +27,21 @@ server/programs/MongoDB/ #generated readme server/worldstorage/README.md +#!ETSI-ARF/Models/ +#!ETSI-ARF/Controllers/ +#!ETSI-ARF/Services/ + # all generated directories +wwwroot/ Attributes/ Authentication/ -Controllers/ Converters/ Filters/ Formatters/ -Models/ OpenAPI/ Properties/ -wwwroot/ +Models +Controllers/ # generated Program.cs #Program.cs diff --git a/readme.md b/readme.md index 7715c17..48846b3 100644 --- a/readme.md +++ b/readme.md @@ -19,14 +19,13 @@ It includes description and code for a fully functional server with MongoDB inte ## Repo Content -| | File / Folder | Description | +| | Files / Folders | Description | |:-:|:--------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| 📂 | openapi | A git submodule (ForgeETSI ) pointing to the repo containing the API specification file | | 📂 | server | The folder where the library code will be generated, the openapi generator is set to not overwrite some files used to generate and initialiue the ASP.Net server system | | 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | -| 📂 | server/src/Org.OpenAPITools | This is the location where the ASP.Net code will be generated | -| 📂 | server/src/Org.OpenAPITools/ControllersImpl | THis folder contains the code implementating the REST end-paths for the different objects in API | -| 📂 | server/src/Org.OpenAPITools/Services | This folder contains MongoDB database settings and access methods for each API | -| 📂 | arf005 | A submodule pointing to the git containing the API specification file | +| 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage | This is the location where the ASP.Net code will be generated | +| 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF | THis folder contains codes implementating the REST end-paths for the different objects in API | ## Requirements @@ -54,13 +53,17 @@ Open `NuGet Package Manager` and add `MongoDB.Driver`. ### File adaptations Change version number in all files if a new version is provided. -### Implementation folder (new) +### Custom folder (new) All custom files are now in the folder 'ETSI-ARF'. Nothing to do adapt manually after generation. But you have to provide the implementation of new endpoints because they are now directly declared as abstract (default). The folder contains following subfolders: -`Controllers` +`ControllersImpl` +`ModelsExt` +`Services` -Compare files folder in "`ETSI-ARF/Controllers`" with the corresponding files in "`Controllers`" and insert if necessary the new methods. +### Folder 'ControllersImp' + +The modules in this folder implement the endpoints. Compare files folder in "`ETSI-ARF/ControllersImpl`" with the corresponding files in "`Controllers`" and implement if necessary the new methods. Methods should be the same with "`override`" instead of "`abstract`". @@ -72,9 +75,11 @@ Add using MongoDB.Driver; ``` -Add a private readonly service class variable like in the already existing files, e.g.: +Add one or more private readonly services class variable like in the already existing files, e.g.: ``` private readonly TrackableService _trackableService; +private readonly WorldAnchorService _worldAnchorService; +private readonly WorldLinkService _worldLinkService; ``` Add a constructor with this service class variable like in the already existing files. @@ -82,13 +87,14 @@ Add a constructor with this service class variable like in the already existing public TrackablesApiControllerImpl(TrackableService trackableService) { _trackableService = trackableService; + // etc. } ``` -Implement endpoint code using the appropriate MogoDB methods of the corresponding classes from the folder `Services` (which you may be have to create). +Implement endpoint code using the appropriate MongoDB methods of the corresponding classes from the folder `Services` (which you may be have to create). -### In the folder `Models` -Add to the classes to be stored in the database (i.e. `Trackable.cs`, `WorldAnchor.cs`, `WorldLink.cs`) inherited from `IModels` (definition of the extra UUID): +### Folder `ModelsExt` +The modules inside this folder are for extensions of the generated API data structures. Add all the classes to be stored in the database (i.e. `TrackableExt.cs`, `WorldAnchorExt.cs`, `WorldLinkExt.cs`) inherited from `IModels`. (definition of the extra UUID): ``` using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; @@ -100,12 +106,17 @@ and at the value that is to become the MongoDB ID, add: [BsonRepresentation(BsonType.String)] ``` +If some members won't be saved in the MongoDB then use this keyword: +``` +[BsonIgnore] +``` + ### Folder `Services` -The folder `Services` should contain one common class with the DatabaseSettings (`DatabaseSettings.cs`) and one with the database-access-methods (create, get, update, remove) for each API. If some are missing create them like the ones you find there. Be aware to add the reference to these in the file `startup.cs` in this case. +The folder `Services` is for handling the data with the MongoDB. It should contain one common class with the DatabaseSettings (`DatabaseSettings.cs`) and one with the database-access-methods (create, get, update, remove) for each API. If some are missing create them like the ones you find there. Be aware to add the reference to these in the file `startup.cs` in this case. The naming in the DatabaseSettings is the same as defined in `appsettings.json`, which you have to extend when creating new classes in this folder. Change `appsettings.json` in the folder `docker` accordingly. Make sure that the ConnectionString for the database contains the correct IP address as specified in `docker-compose.yml`. -### In the folder `wwwroot` +## Extra folder `wwwroot` Add in `openapi-original.json` in section `servers` the urls of the servers you want to use with swagger-ui # MongoDB diff --git a/server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs b/server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs deleted file mode 100644 index b3d314f..0000000 --- a/server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs +++ /dev/null @@ -1,102 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -/* - * World Storage API - * - * API ensuring interoperability between an authoring tool and a World Storage service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Http; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using Org.OpenAPITools.Attributes; -using Org.OpenAPITools.Models; -using Microsoft.OpenApi.Models; - -namespace Org.OpenAPITools.Controllers -{ - /// - /// - /// - [ApiController] - public class DefaultApiControllerImpl : DefaultApiController - { - - /// - /// Get the state of the server. - /// - /// OK, world storage server ready. - [HttpGet] - [Route("/admin")] - [ValidateModelState] - [SwaggerOperation("GetAdmin")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, world storage server ready.")] - public override IActionResult GetAdmin() - { - string version = "OK world storage server ready"; - return new ObjectResult(version); - //return StatusCode(200, new ObjectResult(version)); - } - - /// - /// Test the server availability. - /// - /// Ok, returns a string message. - [HttpGet] - [Route("/ping")] - [ValidateModelState] - [SwaggerOperation("GetPing")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "Ok, returns a string message.")] - public override IActionResult GetPing() - { - string answer = "OK, world storage alive."; - return new ObjectResult(answer); - // return StatusCode(200, new ObjectResult(answer)); - } - - /// - /// Get the version of the ARF API. - /// - /// Current version. - [HttpGet] - [Route("/version")] - [ValidateModelState] - [SwaggerOperation("GetVersion")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "Current version.")] - public override IActionResult GetVersion() - { - string version = "1.0.0"; - return new ObjectResult(version); - //return StatusCode(200, new ObjectResult(version)); - } - - } -} diff --git a/server/src/Org.OpenAPITools/ControllersImpl/TrackablesApiImpl.cs b/server/src/Org.OpenAPITools/ControllersImpl/TrackablesApiImpl.cs deleted file mode 100644 index 39ded8d..0000000 --- a/server/src/Org.OpenAPITools/ControllersImpl/TrackablesApiImpl.cs +++ /dev/null @@ -1,220 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -/* - * World Storage API - * - * API ensuring interoperability between an authoring tool and a World Storage service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Http; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using Org.OpenAPITools.Attributes; -using Org.OpenAPITools.Models; -using Org.OpenAPITools.Services; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Controllers -{ - /// - /// - /// - [ApiController] - public class TrackablesApiControllerImpl : TrackablesApiController - { - - private readonly TrackableService _trackableService; - - /// - /// - /// - public TrackablesApiControllerImpl(TrackableService trackableService) - { - _trackableService = trackableService; - } - - - /// - /// Create a Trackable. - /// - /// Create a new Trackable from a json object containing all the required informations and add it to the world storage. <br>As a result you will get the ID of the newly created Trackable. - /// The Trackable to be added to the world storage. - /// OK, return the UUID of the Trackable defined by the world storage. - /// Null response. - /// Bad request. - /// Invalid UUID, id must be a Nil value. - /// Unexpected error. - [HttpPost] - [Route("/trackables")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("AddTrackable")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the Trackable defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 409, type: typeof(string), description: "Invalid UUID, id must be a Nil value.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult AddTrackable([FromBody] Trackable trackable) - { - if (String.IsNullOrEmpty(trackable.UUID.ToString())) - { - trackable.UUID = Guid.NewGuid(); - } - try - { - Trackable mytrackable = _trackableService.Create(trackable); - return StatusCode(200, mytrackable.UUID.ToString()); - } - catch (Exception e) - { - return StatusCode(400, e.Message); - } - } - - /// - /// Delete a Trackable. - /// - /// Delete a single Trackable stored in the world storage from its ID. - /// Trackable UUID to delete. - /// OK, delete successful. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpDelete] - [Route("/trackables/{trackableUUID}")] - [ValidateModelState] - [SwaggerOperation("DeleteTrackable")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, delete successful.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult DeleteTrackable([FromRoute(Name = "trackableUUID")][Required] Guid trackableUUID) - { - DeleteResult answer = _trackableService.Remove(trackableUUID); - // check, if used in WorldLink - string result = "ok"; - string worldlinkinfo = ""; - List worldlinklistfrom = _trackableService.GetWorldLinkUUIDFrom(trackableUUID); - foreach (WorldLink worldlink in worldlinklistfrom) - { - worldlinkinfo += worldlink.UUID.ToString() + "; "; - worldlink.UUIDFrom = Guid.Empty; - worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - _trackableService.UpdateWorldLink(worldlink.UUID, worldlink); - } - List worldlinklistto = _trackableService.GetWorldLinkUUIDTo(trackableUUID); - foreach (WorldLink worldlink in worldlinklistto) - { - worldlinkinfo += worldlink.UUID.ToString() + "; "; - worldlink.UUIDTo = Guid.Empty; - worldlink.TypeTo = ObjectType.NotIdentifiedEnum; - _trackableService.UpdateWorldLink(worldlink.UUID, worldlink); - } - if (worldlinkinfo.Length > 1) - { - result += ", removed object was referenced in " + worldlinkinfo + " and removed there as well"; - } - return (answer.IsAcknowledged && answer.DeletedCount > 0) ? new ObjectResult(result) : StatusCode(404, "Not found, could not find UUID in database."); - } - - /// - /// Find a Trackable by its UUID. - /// - /// Get a single Trackable stored in the world storage from its ID. - /// UUID of the Trackable to retrieve. - /// Successful operation. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpGet] - [Route("/trackables/{trackableUUID}")] - [ValidateModelState] - [SwaggerOperation("GetTrackableById")] - [SwaggerResponse(statusCode: 200, type: typeof(Trackable), description: "Successful operation.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult GetTrackableById([FromRoute(Name = "trackableUUID")][Required] Guid trackableUUID) - { - Trackable trackable = _trackableService.Get(trackableUUID); - return (null != trackable) ? new ObjectResult(trackable) : StatusCode(404, "Not found, could not find UUID in database."); - } - - /// - /// Return all the Trackables. - /// - /// Get all the Trackables currently being stored in the world storage. - /// OK, return all the Trackables defined by the world storage. - /// Null response. - /// Unexpected error. - [HttpGet] - [Route("/trackables")] - [ValidateModelState] - [SwaggerOperation("GetTrackables")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK, return all the Trackables defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult GetTrackables() - { - List trackablelist = _trackableService.Get(); - return new ObjectResult(trackablelist); - } - - - - /// - /// Modify a Trackable. - /// - /// Modify an existing Trackable given a json object containing all the required informations. <br> **Please note that ID of the object is required in the JSON** - /// The Trackable to be modified in the world storage. - /// OK, return the UUID of the modified Trackable. - /// Bad request. - /// Not found, could not find UUID in database. - /// Unexpected error. - [HttpPut] - [Route("/trackables")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("ModifyTrackable")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the modified Trackable.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult ModifyTrackable([FromBody] Trackable trackable) - { - ReplaceOneResult result = _trackableService.Update(trackable.UUID, trackable); - if (result.MatchedCount == 0) - { - return StatusCode(404, "Not found, could not find UUID in database."); - } - else - { - return StatusCode(200, trackable.UUID.ToString()); - } - } - } -} diff --git a/server/src/Org.OpenAPITools/ControllersImpl/WorldAnchorsApiImpl.cs b/server/src/Org.OpenAPITools/ControllersImpl/WorldAnchorsApiImpl.cs deleted file mode 100644 index 9bb4100..0000000 --- a/server/src/Org.OpenAPITools/ControllersImpl/WorldAnchorsApiImpl.cs +++ /dev/null @@ -1,222 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -/* - * World Storage API - * - * API ensuring interoperability between an authoring tool and a World Storage service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Http; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using Org.OpenAPITools.Attributes; -using Org.OpenAPITools.Models; -using Org.OpenAPITools.Services; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Controllers -{ - /// - /// - /// - [ApiController] - public class WorldAnchorsApiControllerImpl : WorldAnchorsApiController - { - - private readonly WorldAnchorService _worldAnchorService; - - /// - /// - /// - public WorldAnchorsApiControllerImpl(WorldAnchorService worldAnchorService) - { - _worldAnchorService = worldAnchorService; - } - - - /// - /// Create a World Anchor. - /// - /// Create a new World Anchor from a json object containing all the required informations and add it to the world storage. <br>As a result you will get the ID of the newly created World Anchor. - /// The World Anchor to be added to the world storage. - /// OK, return the UUID of the World Anchor defined by the world storage. - /// Null response. - /// Bad request. - /// Invalid UUID, id must be a Nil value. - /// Unexpected error. - [HttpPost] - [Route("/worldAnchors")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("AddWorldAnchor")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the World Anchor defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 409, type: typeof(string), description: "Invalid UUID, id must be a Nil value.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult AddWorldAnchor([FromBody] WorldAnchor worldAnchor) - { - if (String.IsNullOrEmpty(worldAnchor.UUID.ToString())) - { - worldAnchor.UUID = Guid.NewGuid(); - } - try - { - WorldAnchor myworldanchor = _worldAnchorService.Create(worldAnchor); - return StatusCode(200, myworldanchor.UUID.ToString()); - } - catch (Exception e) - { - return StatusCode(400, e.Message); - } - } - - /// - /// Delete a World Anchor. - /// - /// Delete a single World Anchor stored in the world storage from its ID. - /// World Anchor UUID to delete. - /// OK, delete successful. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpDelete] - [Route("/worldAnchors/{worldAnchorUUID}")] - [ValidateModelState] - [SwaggerOperation("DeleteWorldAnchor")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, delete successful.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult DeleteWorldAnchor([FromRoute(Name = "worldAnchorUUID")][Required] Guid worldAnchorUUID) - { - DeleteResult answer = _worldAnchorService.Remove((worldAnchorUUID)); - // check, if used in WorldLink - string result = "ok"; - string worldlinkinfo = ""; - List worldlinklistfrom = _worldAnchorService.GetWorldLinkUUIDFrom(worldAnchorUUID); - foreach (WorldLink worldlink in worldlinklistfrom) - { - worldlinkinfo += worldlink.UUID.ToString() + "; "; - worldlink.UUIDFrom = Guid.Empty; - worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - _worldAnchorService.UpdateWorldLink(worldlink.UUID, worldlink); - } - List worldlinklistto = _worldAnchorService.GetWorldLinkUUIDTo(worldAnchorUUID); - foreach (WorldLink worldlink in worldlinklistto) - { - worldlinkinfo += worldlink.UUID.ToString() + "; "; - worldlink.UUIDTo = Guid.Empty; - worldlink.TypeTo = ObjectType.NotIdentifiedEnum; - _worldAnchorService.UpdateWorldLink(worldlink.UUID, worldlink); - } - if (worldlinkinfo.Length > 1) - { - result += ", but removed object was referenced in " + worldlinkinfo + " and removed there as well"; - } - return (answer.IsAcknowledged && answer.DeletedCount > 0) ? new ObjectResult(result) : StatusCode(404, "Not found, could not find UUID in database."); - } - - /// - /// Find a World Anchor by its UUID. - /// - /// Get a single World Anchor stored in the world storage from its ID. - /// UUID of the World Anchor to retrieve. - /// Successful operation. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpGet] - [Route("/worldAnchors/{worldAnchorUUID}")] - [ValidateModelState] - [SwaggerOperation("GetWorldAnchorById")] - [SwaggerResponse(statusCode: 200, type: typeof(WorldAnchor), description: "Successful operation.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult GetWorldAnchorById([FromRoute(Name = "worldAnchorUUID")][Required] Guid worldAnchorUUID) - { - WorldAnchor myworldanchor = _worldAnchorService.Get(worldAnchorUUID); - return (null != myworldanchor) ? new ObjectResult(myworldanchor) : StatusCode(404, "Not found, could not find UUID in database."); - } - - /// - /// Return all the World Anchors. - /// - /// Get all the World Anchors currently being stored in the world storage. - /// OK, return all the World Anchors defined by the world storage. - /// Null response. - /// Unexpected error. - [HttpGet] - [Route("/worldAnchors")] - [ValidateModelState] - [SwaggerOperation("GetWorldAnchors")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK, return all the World Anchors defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult GetWorldAnchors() - { - List worldanchorlist = _worldAnchorService.Get(); - return new ObjectResult(worldanchorlist); - } - - - - /// - /// Modify a World Anchor. - /// - /// Modify an existing World Anchor given a json object containing all the required informations. <br> **Please note that ID of the object is required in the JSON** - /// The World Anchor to be modified in the world storage. - /// OK, return the UUID of the modified World Anchor. - /// Bad request. - /// Not found, could not find UUID in database. - /// Unexpected error. - [HttpPut] - [Route("/worldAnchors")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("ModifyWorldAnchor")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the modified World Anchor.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult ModifyWorldAnchor([FromBody] WorldAnchor worldAnchor) - { - ReplaceOneResult result = _worldAnchorService.Update(worldAnchor.UUID, worldAnchor); - if (result.MatchedCount == 0) - { - return StatusCode(404, "Not found, could not find UUID in database."); - } - else - { - return StatusCode(200, worldAnchor.UUID.ToString()); - } - } - - - } -} diff --git a/server/src/Org.OpenAPITools/ControllersImpl/WorldLinksApiImpl.cs b/server/src/Org.OpenAPITools/ControllersImpl/WorldLinksApiImpl.cs deleted file mode 100644 index 0cb2b03..0000000 --- a/server/src/Org.OpenAPITools/ControllersImpl/WorldLinksApiImpl.cs +++ /dev/null @@ -1,271 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -/* - * World Storage API - * - * API ensuring interoperability between an authoring tool and a World Storage service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Http; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using Org.OpenAPITools.Attributes; -using Org.OpenAPITools.Models; -using Org.OpenAPITools.Services; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Controllers -{ - /// - /// - /// - [ApiController] - public class WorldLinksApiControllerImpl : WorldLinksApiController - { - - private readonly WorldLinkService _worldLinkService; - - /// - /// - /// - public WorldLinksApiControllerImpl(WorldLinkService worldLinkService) - { - _worldLinkService = worldLinkService; - } - - /// - /// Create a World Link between elements (world anchors and/or trackables). - /// - /// Create a new World Link from a json object containing all the required informations and add it to the world storage. <br>As a result you will get the ID of the newly created World Link. - /// The link to be added to the world storage. - /// OK, return the UUID of the World Link defined by the world storage. - /// Null response. - /// Bad request. - /// Invalid UUID, id must be a Nil value. - /// Unexpected error. - [HttpPost] - [Route("/worldLinks")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("AddWorldLink")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the World Link defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 409, type: typeof(string), description: "Invalid UUID, id must be a Nil value.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult AddWorldLink([FromBody] WorldLink worldLink) - { - if (String.IsNullOrEmpty(worldLink.UUID.ToString())) - { - worldLink.UUID = Guid.NewGuid(); - } - try - { - WorldLink myworldlink = _worldLinkService.Create(worldLink); - return StatusCode(200, myworldlink.UUID.ToString()); - } - catch (Exception e) - { - return StatusCode(400, e.Message); - } - } - - /// - /// Delete a World Link. - /// - /// Delete a single World Link stored in the world storage from its ID. - /// World Link id to delete. - /// OK, delete successful. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpDelete] - [Route("/worldLinks/{worldLinkUUID}")] - [ValidateModelState] - [SwaggerOperation("DeleteWorldLink")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, delete successful.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult DeleteWorldLink([FromRoute(Name = "worldLinkUUID")][Required] Guid worldLinkUUID) - { - DeleteResult answer = _worldLinkService.Remove((worldLinkUUID)); - return (answer.IsAcknowledged && answer.DeletedCount > 0) ? new ObjectResult("ok") : StatusCode(404, "Not found, could not find UUID in database."); - } - - - /// - /// Find a World Link by its UUID. - /// - /// Get a single World Link stored in the world storage from its ID. - /// UUID of the World Link to retrieve. - /// Successful operation. - /// Invalid UUID supplied. - /// Not found, could not find UUID in database. - [HttpGet] - [Route("/worldLinks/{worldLinkUUID}")] - [ValidateModelState] - [SwaggerOperation("GetWorldLinkById")] - [SwaggerResponse(statusCode: 200, type: typeof(WorldLink), description: "Successful operation.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Invalid UUID supplied.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - public override IActionResult GetWorldLinkById([FromRoute(Name = "worldLinkUUID")][Required] Guid worldLinkUUID) - { - WorldLink myworldlink = _worldLinkService.Get(worldLinkUUID); - if (null != myworldlink) - { - // check TypeFrom - if (myworldlink.TypeFrom == ObjectType.TrackableEnum) - { - if (null == _worldLinkService.GetTrackable(myworldlink.UUIDFrom)) - { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDFrom = Guid.Empty; - } - } - else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) - { - if (null == _worldLinkService.GetAnchor(myworldlink.UUIDFrom)) - { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDFrom = Guid.Empty; - } - } - // check TypeTo - if (myworldlink.TypeTo == ObjectType.TrackableEnum) - { - if (null == _worldLinkService.GetTrackable(myworldlink.UUIDTo)) - { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDTo = Guid.Empty; - } - } - else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) - { - if (null == _worldLinkService.GetAnchor(myworldlink.UUIDTo)) - { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDTo = Guid.Empty; - } - } - } - return (null != myworldlink) ? new ObjectResult(myworldlink) : StatusCode(404, "Not found, could not find UUID in database."); - } - - /// - /// Return all World Links. - /// - /// Get all the World Links currently being stored in the world storage. - /// OK return all the World Links defined by the world storage. - /// Null response. - /// Unexpected error. - [HttpGet] - [Route("/worldLinks")] - [ValidateModelState] - [SwaggerOperation("GetWorldLinks")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK return all the World Links defined by the world storage.")] - [SwaggerResponse(statusCode: 201, type: typeof(string), description: "Null response.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult GetWorldLinks() - { - List worldlinklist = _worldLinkService.Get(); - foreach (WorldLink myworldlink in worldlinklist) - { - // check TypeFrom - if (myworldlink.TypeFrom == ObjectType.TrackableEnum) - { - if (null == _worldLinkService.GetTrackable(myworldlink.UUIDFrom)) - { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDFrom = Guid.Empty; - } - } - else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) - { - if (null == _worldLinkService.GetAnchor(myworldlink.UUIDFrom)) - { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDFrom = Guid.Empty; - } - } - // check TypeTo - if (myworldlink.TypeTo == ObjectType.TrackableEnum) - { - if (null == _worldLinkService.GetTrackable(myworldlink.UUIDTo)) - { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDTo = Guid.Empty; - } - } - else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) - { - if (null == _worldLinkService.GetAnchor(myworldlink.UUIDTo)) - { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; - myworldlink.UUIDTo = Guid.Empty; - } - } - } - return new ObjectResult(worldlinklist); - } - - - - /// - /// Modify a World Link. - /// - /// Modify an existing World Link given a json object containing all the required informations. <br> **Please note that ID of the object is required in the JSON** - /// The World Link to be modified in the world storage. - /// OK, return the UUID of the modified World Link. - /// Bad request. - /// Not found, could not find UUID in database. - /// Unexpected error. - [HttpPut] - [Route("/worldLinks")] - [Consumes("application/json")] - [ValidateModelState] - [SwaggerOperation("ModifyWorldLink")] - [SwaggerResponse(statusCode: 200, type: typeof(string), description: "OK, return the UUID of the modified World Link.")] - [SwaggerResponse(statusCode: 400, type: typeof(string), description: "Bad request.")] - [SwaggerResponse(statusCode: 404, type: typeof(string), description: "Not found, could not find UUID in database.")] - [SwaggerResponse(statusCode: 0, type: typeof(Error), description: "Unexpected error.")] - public override IActionResult ModifyWorldLink([FromBody] WorldLink worldLink) - { - ReplaceOneResult result = _worldLinkService.Update(worldLink.UUID, worldLink); - if (result.MatchedCount == 0) - { - return StatusCode(404, "Not found, could not find UUID in database."); - } - else - { - return StatusCode(200, worldLink.UUID.ToString()); - } - } - } -} diff --git a/server/src/Org.OpenAPITools/Dockerfile b/server/src/Org.OpenAPITools/Dockerfile deleted file mode 100644 index 267d1df..0000000 --- a/server/src/Org.OpenAPITools/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. - -# Container we use for final publish -FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base -WORKDIR /app -EXPOSE 80 -EXPOSE 443 - -# Build container -FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build - -# Copy the code into the container -WORKDIR /src -COPY ["Org.OpenAPITools.csproj", "Org.OpenAPITools/"] - -# NuGet restore -RUN dotnet restore "Org.OpenAPITools/Org.OpenAPITools.csproj" -COPY [".", "Org.OpenAPITools/"] - -# Build the API -WORKDIR "Org.OpenAPITools" -RUN dotnet build "Org.OpenAPITools.csproj" -c Release -o /app/build - -# Publish it -FROM build AS publish -RUN dotnet publish "Org.OpenAPITools.csproj" -c Release -o /app/publish - -# Make the final image for publishing -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "Org.OpenAPITools.dll"] diff --git a/server/src/Org.OpenAPITools/Services/TrackableService.cs b/server/src/Org.OpenAPITools/Services/TrackableService.cs deleted file mode 100644 index a115449..0000000 --- a/server/src/Org.OpenAPITools/Services/TrackableService.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Org.OpenAPITools.Models; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Services -{ - public class TrackableService - { - private readonly IMongoCollection _trackablecollection; - private readonly IMongoCollection _worldlinkcollection; - - /// - /// - /// - public TrackableService(IDatabaseSettings settings) - { - var client = new MongoClient(settings.ConnectionString); - var database = client.GetDatabase(settings.DatabaseName); - - _trackablecollection = database.GetCollection(settings.CollectionNameTrackables); - _worldlinkcollection = database.GetCollection(settings.CollectionNameWorldLink); - } - - public List Get() => - _trackablecollection.Find(trackable => true).ToList(); - - public List Get(int limit) => - _trackablecollection.Find(trackable => true).Limit(limit).ToList(); - - public Trackable Get(Guid UUID) => - _trackablecollection.Find(trackable => trackable.UUID == UUID).FirstOrDefault(); - - public Trackable Create(Trackable trackable) - { - _trackablecollection.InsertOne(trackable); - return trackable; - } - - public ReplaceOneResult Update(Guid UUID, Trackable trackableIn) => - _trackablecollection.ReplaceOne(trackable => trackable.UUID == UUID, trackableIn); - - public DeleteResult Remove(Trackable trackableIn) => - _trackablecollection.DeleteOne(trackable => trackable.UUID == trackableIn.UUID); - - public DeleteResult Remove(Guid UUID) => - _trackablecollection.DeleteOne(trackable => trackable.UUID == UUID); - - - - /* WorldLink */ - public List GetWorldLinkUUIDFrom(Guid UUID) => - _worldlinkcollection.Find(worldlink => worldlink.UUIDFrom == UUID).ToList(); - - public List GetWorldLinkUUIDTo(Guid UUID) => - _worldlinkcollection.Find(worldlink => worldlink.UUIDTo == UUID).ToList(); - - public ReplaceOneResult UpdateWorldLink(Guid UUID, WorldLink worldlinkIn) => - _worldlinkcollection.ReplaceOne(worldlink => worldlink.UUID == UUID, worldlinkIn); - - } - -} - diff --git a/server/src/Org.OpenAPITools/Services/WorldAnchorService.cs b/server/src/Org.OpenAPITools/Services/WorldAnchorService.cs deleted file mode 100644 index 8a6e7c6..0000000 --- a/server/src/Org.OpenAPITools/Services/WorldAnchorService.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Org.OpenAPITools.Models; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Services -{ - public class WorldAnchorService - { - private readonly IMongoCollection _worldanchorcollection; - private readonly IMongoCollection _worldlinkcollection; - - /// - /// - /// - public WorldAnchorService(IDatabaseSettings settings) - { - var client = new MongoClient(settings.ConnectionString); - var database = client.GetDatabase(settings.DatabaseName); - - _worldanchorcollection = database.GetCollection(settings.CollectionNameWorldAnchor); - _worldlinkcollection = database.GetCollection(settings.CollectionNameWorldLink); - } - - public List Get() => - _worldanchorcollection.Find(worldanchor => true).ToList(); - - public List Get(int limit) => - _worldanchorcollection.Find(worldanchor => true).Limit(limit).ToList(); - - public WorldAnchor Get(Guid UUID) => - _worldanchorcollection.Find(worldanchor => worldanchor.UUID == UUID).FirstOrDefault(); - - public WorldAnchor Create(WorldAnchor worldanchor) - { - _worldanchorcollection.InsertOne(worldanchor); - return worldanchor; - } - - public ReplaceOneResult Update(Guid UUID, WorldAnchor worldanchorIn) => - _worldanchorcollection.ReplaceOne(worldanchor => worldanchor.UUID == UUID, worldanchorIn); - - public DeleteResult Remove(WorldAnchor worldanchorIn) => - _worldanchorcollection.DeleteOne(worldanchor => worldanchor.UUID == worldanchorIn.UUID); - - public DeleteResult Remove(Guid UUID) => - _worldanchorcollection.DeleteOne(worldanchor => worldanchor.UUID == UUID); - - - /* WorldLink */ - public List GetWorldLinkUUIDFrom(Guid UUID) => - _worldlinkcollection.Find(worldlink => worldlink.UUIDFrom == UUID).ToList(); - - public List GetWorldLinkUUIDTo(Guid UUID) => - _worldlinkcollection.Find(worldlink => worldlink.UUIDTo == UUID).ToList(); - public ReplaceOneResult UpdateWorldLink(Guid UUID, WorldLink worldlinkIn) => - _worldlinkcollection.ReplaceOne(worldlink => worldlink.UUID == UUID, worldlinkIn); - } - -} - diff --git a/server/src/Org.OpenAPITools/Services/WorldLinkService.cs b/server/src/Org.OpenAPITools/Services/WorldLinkService.cs deleted file mode 100644 index 073c597..0000000 --- a/server/src/Org.OpenAPITools/Services/WorldLinkService.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Org.OpenAPITools.Models; -using MongoDB.Driver; - -namespace Org.OpenAPITools.Services -{ - public class WorldLinkService - { - private readonly IMongoCollection _worldlinkcollection; - private readonly IMongoCollection _worldanchorcollection; - private readonly IMongoCollection _trackablecollection; - - /// - /// - /// - public WorldLinkService(IDatabaseSettings settings) - { - var client = new MongoClient(settings.ConnectionString); - var database = client.GetDatabase(settings.DatabaseName); - - _worldlinkcollection = database.GetCollection(settings.CollectionNameWorldLink); - _worldanchorcollection = database.GetCollection(settings.CollectionNameWorldAnchor); - _trackablecollection = database.GetCollection(settings.CollectionNameTrackables); - } - - public List Get() => - _worldlinkcollection.Find(worldlink => true).ToList(); - - public List Get(int limit) => - _worldlinkcollection.Find(worldlink => true).Limit(limit).ToList(); - - public WorldLink Get(Guid UUID) => - _worldlinkcollection.Find(worldlink => worldlink.UUID == UUID).FirstOrDefault(); - - public WorldLink Create(WorldLink worldlink) - { - _worldlinkcollection.InsertOne(worldlink); - return worldlink; - } - - public ReplaceOneResult Update(Guid UUID, WorldLink worldlinkIn) => - _worldlinkcollection.ReplaceOne(worldlink => worldlink.UUID == UUID, worldlinkIn); - - public DeleteResult Remove(WorldLink worldlinkIn) => - _worldlinkcollection.DeleteOne(worldlink => worldlink.UUID == worldlinkIn.UUID); - - public DeleteResult Remove(Guid UUID) => - _worldlinkcollection.DeleteOne(worldlink => worldlink.UUID == UUID); - - - /*********************/ - public WorldAnchor GetAnchor(Guid UUID) => - _worldanchorcollection.Find(worldanchor => worldanchor.UUID == UUID).FirstOrDefault(); - - public Trackable GetTrackable(Guid UUID) => - _trackablecollection.Find(trackable => trackable.UUID == UUID).FirstOrDefault(); - - } -} - diff --git a/server/src/Org.OpenAPITools/Startup.cs b/server/src/Org.OpenAPITools/Startup.cs deleted file mode 100644 index a3ee347..0000000 --- a/server/src/Org.OpenAPITools/Startup.cs +++ /dev/null @@ -1,180 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -/* - * World Storage API - * - * API ensuring interoperability between an authoring tool and a World Storage service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.IO; -using System.Reflection; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using Org.OpenAPITools.Authentication; -using Org.OpenAPITools.Filters; -using Org.OpenAPITools.OpenApi; -using Org.OpenAPITools.Formatters; -using Org.OpenAPITools.Services; -using MongoDB.Bson.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Serializers; -using Microsoft.Extensions.Options; - -namespace Org.OpenAPITools -{ - /// - /// Startup - /// - public class Startup - { - /// - /// Constructor - /// - /// - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - /// - /// The application configuration. - /// - public IConfiguration Configuration { get; } - - /// - /// This method gets called by the runtime. Use this method to add services to the container. - /// - /// - public void ConfigureServices(IServiceCollection services) - { - BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)); - BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; - // requires using Microsoft.Extensions.Options - services.Configure( - Configuration.GetSection(nameof(DatabaseSettings))); - services.AddSingleton(sp => - sp.GetRequiredService>().Value); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - // Add framework services. - services - // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ - .AddControllers(options => - { - options.InputFormatters.Insert(0, new InputFormatterStream()); - }) - .AddNewtonsoftJson(opts => - { - opts.SerializerSettings.ContractResolver = new DefaultContractResolver(); - /* opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - opts.SerializerSettings.Converters.Add(new StringEnumConverter - { - NamingStrategy = new CamelCaseNamingStrategy() - });*/ - }); - - services - .AddSwaggerGen(c => - { - c.SwaggerDoc("1.0.0", new OpenApiInfo - { - Title = "World Storage API", - Description = "World Storage API (ASP.NET Core 3.1)", - TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"), - Contact = new OpenApiContact - { - Name = "OpenAPI-Generator Contributors", - Url = new Uri("https://github.com/openapitools/openapi-generator"), - Email = "" - }, - License = new OpenApiLicense - { - Name = "NoLicense", - Url = new Uri("https://opensource.org/licenses/BSD-3-Clause") - }, - Version = "1.0.0", - }); - c.CustomSchemaIds(type => type.FriendlyId(true)); - c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml"); - - // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..) - // Use [ValidateModelState] on Actions to actually validate it in C# as well! - c.OperationFilter(); - }); - services - .AddSwaggerGenNewtonsoftSupport(); - } - - /// - /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - /// - /// - /// - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseHsts(); - } - - app.UseHttpsRedirection(); - app.UseDefaultFiles(); - app.UseStaticFiles(); - app.UseSwagger(c => - { - c.RouteTemplate = "openapi/{documentName}/openapi.json"; - }) - .UseSwaggerUI(c => - { - // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html - c.RoutePrefix = "openapi"; - //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes) - //c.SwaggerEndpoint("/openapi/1.0.0/openapi.json", "World Storage API"); - - //TODO: Or alternatively use the original OpenAPI contract that's included in the static files - c.SwaggerEndpoint("/openapi-original.json", "World Storage API Original"); - }); - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - } -} diff --git a/server/src/Org.OpenAPITools/appsettings.json b/server/src/Org.OpenAPITools/appsettings.json deleted file mode 100644 index aebd1bb..0000000 --- a/server/src/Org.OpenAPITools/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "DatabaseSettings": { - "CollectionNameWorldLink": "WorldLink", - "CollectionNameTrackables": "Trackables", - "CollectionNameWorldAnchor": "WorldAnchor", - "ConnectionString": "mongodb://localhost:27017", - "DatabaseName": "WorldStorageAPI" - }, - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/server/src/Org.OpenAPITools/docker-compose.yml b/server/src/Org.OpenAPITools/docker-compose.yml deleted file mode 100644 index 4bf9963..0000000 --- a/server/src/Org.OpenAPITools/docker-compose.yml +++ /dev/null @@ -1,41 +0,0 @@ -# Please refer https://aka.ms/HTTPSinContainer on how to setup an https developer certificate for your ASP .NET Core service. - -version: '3.4' - -networks: - vpcbr: - ipam: - config: - - subnet: 10.10.20.0/24 - -services: - worldstorageapi: - image: org.openapitools:latest - volumes: - - ./docker/appsettings.json:/app/appsettings.json:rw - ports: - - 8080:8080 - networks: - vpcbr: - ipv4_address: 10.10.20.101 - restart: unless-stopped - - mongodatabase: - image: mongo:latest - container_name: mongodatabase - environment: - - PUID=1000 - - PGID=1000 - volumes: - - mongodbdata:/data/db:rw - - ./docker/data-dump:/data-dump - ports: - - 27017:27017 - - 28017:28017 - networks: - vpcbr: - ipv4_address: 10.10.20.100 - restart: unless-stopped - -volumes: - mongodbdata: \ No newline at end of file diff --git a/server/src/Org.OpenAPITools/docker/appsettings.json b/server/src/Org.OpenAPITools/docker/appsettings.json deleted file mode 100644 index 28066ba..0000000 --- a/server/src/Org.OpenAPITools/docker/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "DatabaseSettings": { - "CollectionNameWorldLink": "WorldLink", - "CollectionNameTrackables": "Trackables", - "CollectionNameWorldAnchor": "WorldAnchor", - "ConnectionString": "mongodb://10.10.20.100:27017", - "DatabaseName": "WorldStorageAPI" - }, - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/server/worldanalysis/.openapi-generator-ignore b/server/worldanalysis/.openapi-generator-ignore deleted file mode 100644 index 7484ee5..0000000 --- a/server/worldanalysis/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# OpenAPI Generator Ignore -# Generated by openapi-generator https://github.com/openapitools/openapi-generator - -# Use this file to prevent files from being overwritten by the generator. -# The patterns follow closely to .gitignore or .dockerignore. - -# As an example, the C# client generator defines ApiClient.cs. -# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: -#ApiClient.cs - -# You can match any string of characters against a directory, file or extension with a single asterisk (*): -#foo/*/qux -# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux - -# You can recursively match patterns against a directory, file or extension with a double asterisk (**): -#foo/**/qux -# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux - -# You can also negate patterns with an exclamation (!). -# For example, you can ignore all files in a docs folder with the file extension .md: -#docs/*.md -# Then explicitly reverse the ignore rule for a single file: -#!docs/README.md diff --git a/server/worldanalysis/README.md b/server/worldanalysis/README.md deleted file mode 100644 index ac3ce3d..0000000 --- a/server/worldanalysis/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# ETSI.ARF.OpenAPI.WorldAnalysis - ASP.NET Core 5.0 Server - -API ensuring interoperability between Scene Management and a World Analysis service - -## Upgrade NuGet Packages - -NuGet packages get frequently updated. - -To upgrade this solution to the latest version of all NuGet packages, use the dotnet-outdated tool. - - -Install dotnet-outdated tool: - -``` -dotnet tool install --global dotnet-outdated-tool -``` - -Upgrade only to new minor versions of packages - -``` -dotnet outdated --upgrade --version-lock Major -``` - -Upgrade to all new versions of packages (more likely to include breaking API changes) - -``` -dotnet outdated --upgrade -``` - - -## Run - -Linux/OS X: - -``` -sh build.sh -``` - -Windows: - -``` -build.bat -``` -## Run in Docker - -``` -cd src/ETSI.ARF.OpenAPI.WorldAnalysis -docker build -t etsi.arf.openapi.worldanalysis . -docker run -p 5000:8080 etsi.arf.openapi.worldanalysis -``` diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore deleted file mode 100644 index 1ee5385..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/.gitignore +++ /dev/null @@ -1,362 +0,0 @@ -## 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 - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 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 -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -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 -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# 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.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -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/ - -# 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 ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile deleted file mode 100644 index 1203a89..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. - -# Container we use for final publish -FROM mcr.microsoft.com/dotnet/core/aspnet:5.0-buster-slim AS base -WORKDIR /app -EXPOSE 80 -EXPOSE 443 - -# Build container -FROM mcr.microsoft.com/dotnet/core/sdk:5.0-buster AS build - -# Copy the code into the container -WORKDIR /src -COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj", "ETSI.ARF.OpenAPI.WorldAnalysis/"] - -# NuGet restore -RUN dotnet restore "ETSI.ARF.OpenAPI.WorldAnalysis/ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -COPY ["src/ETSI.ARF.OpenAPI.WorldAnalysis/", "ETSI.ARF.OpenAPI.WorldAnalysis/"] - -# Build the API -WORKDIR "ETSI.ARF.OpenAPI.WorldAnalysis" -RUN dotnet build "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/build - -# Publish it -FROM build AS publish -RUN dotnet publish "ETSI.ARF.OpenAPI.WorldAnalysis.csproj" -c Release -o /app/publish - -# Make the final image for publishing -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "ETSI.ARF.OpenAPI.WorldAnalysis.dll"] diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs deleted file mode 100644 index 95e2206..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Program.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - -namespace ETSI.ARF.OpenAPI.WorldAnalysis -{ - /// - /// Program - /// - public class Program - { - /// - /// Main - /// - /// - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - /// - /// Create the host builder. - /// - /// - /// IHostBuilder - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup() - .UseUrls("http://0.0.0.0:8080/"); - }); - } -} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs deleted file mode 100644 index eca5631..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/Startup.cs +++ /dev/null @@ -1,144 +0,0 @@ -/* - * World Analysis API - * - * API ensuring interoperability between Scene Management and a World Analysis service - * - * The version of the OpenAPI document: 1.0.0 - * - * Generated by: https://openapi-generator.tech - */ - -using System; -using System.IO; -using System.Reflection; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.OpenApi.Models; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using ETSI.ARF.OpenAPI.WorldAnalysis.Authentication; -using ETSI.ARF.OpenAPI.WorldAnalysis.Filters; -using ETSI.ARF.OpenAPI.WorldAnalysis.OpenApi; -using ETSI.ARF.OpenAPI.WorldAnalysis.Formatters; - -namespace ETSI.ARF.OpenAPI.WorldAnalysis -{ - /// - /// Startup - /// - public class Startup - { - /// - /// Constructor - /// - /// - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - /// - /// The application configuration. - /// - public IConfiguration Configuration { get; } - - /// - /// This method gets called by the runtime. Use this method to add services to the container. - /// - /// - public void ConfigureServices(IServiceCollection services) - { - - // Add framework services. - services - // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ - .AddControllers(options => { - options.InputFormatters.Insert(0, new InputFormatterStream()); - }) - .AddNewtonsoftJson(opts => - { - opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - opts.SerializerSettings.Converters.Add(new StringEnumConverter - { - NamingStrategy = new CamelCaseNamingStrategy() - }); - }); - services - .AddSwaggerGen(c => - { - c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); - - c.SwaggerDoc("1.0.0", new OpenApiInfo - { - Title = "World Analysis API", - Description = "World Analysis API (ASP.NET Core 5.0)", - TermsOfService = new Uri("https://github.com/openapitools/openapi-generator"), - Contact = new OpenApiContact - { - Name = "OpenAPI-Generator Contributors", - Url = new Uri("https://github.com/openapitools/openapi-generator"), - Email = "" - }, - License = new OpenApiLicense - { - Name = "NoLicense", - Url = new Uri("https://opensource.org/licenses/BSD-3-Clause") - }, - Version = "1.0.0", - }); - c.CustomSchemaIds(type => type.FriendlyId(true)); - c.IncludeXmlComments($"{AppContext.BaseDirectory}{Path.DirectorySeparatorChar}{Assembly.GetEntryAssembly().GetName().Name}.xml"); - - // Include DataAnnotation attributes on Controller Action parameters as OpenAPI validation rules (e.g required, pattern, ..) - // Use [ValidateModelState] on Actions to actually validate it in C# as well! - c.OperationFilter(); - }); - services - .AddSwaggerGenNewtonsoftSupport(); - } - - /// - /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - /// - /// - /// - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseHsts(); - } - - app.UseHttpsRedirection(); - app.UseDefaultFiles(); - app.UseStaticFiles(); - app.UseSwagger(c => - { - c.RouteTemplate = "openapi/{documentName}/openapi.json"; - }) - .UseSwaggerUI(c => - { - // set route prefix to openapi, e.g. http://localhost:8080/openapi/index.html - c.RoutePrefix = "openapi"; - //TODO: Either use the SwaggerGen generated OpenAPI contract (generated from C# classes) - c.SwaggerEndpoint("/openapi/1.0.0/openapi.json", "World Analysis API"); - - //TODO: Or alternatively use the original OpenAPI contract that's included in the static files - // c.SwaggerEndpoint("/openapi-original.json", "World Analysis API Original"); - }); - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - } -} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json deleted file mode 100644 index e203e94..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json b/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json deleted file mode 100644 index def9159..0000000 --- a/server/worldanalysis/src/ETSI.ARF.OpenAPI.WorldAnalysis/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/DefaultImpl.cs similarity index 98% rename from server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs rename to server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/DefaultImpl.cs index 6c48dcd..ea5c39b 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Controllers/DefaultApiExt.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/DefaultImpl.cs @@ -29,7 +29,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers /// /// /// - public class DefaultApiControllerExt : DefaultApiController + public class DefaultApiControllerImpl : DefaultApiController { public override IActionResult GetPing() { @@ -45,7 +45,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers public override IActionResult GetVersion() { - string answer = "ETSI ARF RESTful API 1.0.1"; + string answer = "ETSI ARF RESTful API 1.1.0"; return new ObjectResult(answer); } diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs new file mode 100644 index 0000000..cc3064a --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs @@ -0,0 +1,158 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +/* + * World Storage API + * + * API ensuring interoperability between an authoring tool and a World Storage service + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Swashbuckle.AspNetCore.Annotations; +using Swashbuckle.AspNetCore.SwaggerGen; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Attributes; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using ETSI.ARF.OpenAPI.WorldStorage.Services; +using MongoDB.Driver; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers +{ + /// + /// + /// + [ApiController] + public class TrackablesApiControllerImpl : TrackablesApiController + { + private readonly TrackableService _trackableService; + private readonly WorldLinkService _worldLinkService; + + /// + /// + /// + public TrackablesApiControllerImpl(TrackableService trackableService, WorldLinkService worldLinkService) + { + _trackableService = trackableService; + _worldLinkService = worldLinkService; + } + + + /// + /// Create a Trackable. + /// + public override IActionResult AddTrackable([FromBody] Trackable trackable, [FromHeader] string token) + { + if (String.IsNullOrEmpty(trackable.UUID.ToString())) + { + trackable.UUID = Guid.NewGuid(); + } + try + { + Trackable mytrackable = _trackableService.Create(trackable); + return StatusCode(200, mytrackable.UUID.ToString()); + } + catch (Exception e) + { + return StatusCode(400, e.Message); + } + } + + /// + /// Delete a Trackable. + /// + public override IActionResult DeleteTrackable([FromRoute(Name = "trackableUUID")][Required] Guid trackableUUID, [FromHeader] string token) + { + long count = _trackableService.Remove(trackableUUID); + // check, if used in WorldLink + string result = "ok"; + string worldlinkinfo = ""; + + // Update world links + List worldlinklistfrom = _worldLinkService.GetWorldLinkUUIDFrom(trackableUUID); + foreach (WorldLink worldlink in worldlinklistfrom) + { + worldlinkinfo += worldlink.UUID.ToString() + "; "; + worldlink.UUIDFrom = Guid.Empty; + worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + _worldLinkService.Replace(worldlink); + } + + // Update world links + List worldlinklistto = _worldLinkService.GetWorldLinkUUIDTo(trackableUUID); + foreach (WorldLink worldlink in worldlinklistto) + { + worldlinkinfo += worldlink.UUID.ToString() + "; "; + worldlink.UUIDTo = Guid.Empty; + worldlink.TypeTo = ObjectType.NotIdentifiedEnum; + _worldLinkService.Replace(worldlink); + } + if (worldlinkinfo.Length > 1) + { + result += ", removed object was referenced in " + worldlinkinfo + " and removed there as well"; + } + return (count > 0) ? new ObjectResult(result) : StatusCode(404, "Not found, could not find UUID in database."); + } + + /// + /// Find a Trackable by its UUID. + /// + public override IActionResult GetTrackableById([FromRoute(Name = "trackableUUID")][Required] Guid trackableUUID, [FromHeader] string token) + { + Trackable trackable = _trackableService.Get(trackableUUID); + return (null != trackable) ? new ObjectResult(trackable) : StatusCode(404, "Not found, could not find UUID in database."); + } + + /// + /// Return all the Trackables. + /// + public override IActionResult GetTrackables([FromHeader] string token) + { + List trackablelist = _trackableService.Get(); + return new ObjectResult(trackablelist); + } + + + + /// + /// Modify a Trackable. + /// + public override IActionResult ModifyTrackable([FromBody] Trackable trackable, [FromHeader] string token) + { + long count = _trackableService.Replace(trackable); + if (count == 0) + { + return StatusCode(404, "Not found, could not find UUID in database."); + } + else + { + return StatusCode(200, trackable.UUID.ToString()); + } + } + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs new file mode 100644 index 0000000..7acf41a --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs @@ -0,0 +1,160 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +/* + * World Storage API + * + * API ensuring interoperability between an authoring tool and a World Storage service + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Swashbuckle.AspNetCore.Annotations; +using Swashbuckle.AspNetCore.SwaggerGen; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Attributes; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using ETSI.ARF.OpenAPI.WorldStorage.Services; +using MongoDB.Driver; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers +{ + /// + /// + /// + [ApiController] + public class WorldAnchorsApiControllerImpl : WorldAnchorsApiController + { + private readonly WorldAnchorService _worldAnchorService; + private readonly WorldLinkService _worldLinkService; + + /// + /// + /// + public WorldAnchorsApiControllerImpl(WorldAnchorService worldAnchorService, WorldLinkService worldLinkService) + { + _worldAnchorService = worldAnchorService; + _worldLinkService = worldLinkService; + } + + + /// + /// Create a World Anchor. + /// + public override IActionResult AddWorldAnchor([FromBody] WorldAnchor worldAnchor, [FromHeader] string token) + { + if (String.IsNullOrEmpty(worldAnchor.UUID.ToString())) + { + worldAnchor.UUID = Guid.NewGuid(); + } + try + { + WorldAnchor myworldanchor = _worldAnchorService.Create(worldAnchor); + return StatusCode(200, myworldanchor.UUID.ToString()); + } + catch (Exception e) + { + return StatusCode(400, e.Message); + } + } + + /// + /// Delete a World Anchor. + /// + public override IActionResult DeleteWorldAnchor([FromRoute(Name = "worldAnchorUUID")][Required] Guid worldAnchorUUID, [FromHeader] string token) + { + long count = _worldAnchorService.Remove(worldAnchorUUID); + // check, if used in WorldLink + string result = "ok"; + string worldlinkinfo = ""; + + // Update world links + List worldlinklistfrom = _worldLinkService.GetWorldLinkUUIDFrom(worldAnchorUUID); + foreach (WorldLink worldlink in worldlinklistfrom) + { + worldlinkinfo += worldlink.UUID.ToString() + "; "; + worldlink.UUIDFrom = Guid.Empty; + worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + _worldLinkService.Replace(worldlink); + } + + // Update world links + List worldlinklistto = _worldLinkService.GetWorldLinkUUIDTo(worldAnchorUUID); + foreach (WorldLink worldlink in worldlinklistto) + { + worldlinkinfo += worldlink.UUID.ToString() + "; "; + worldlink.UUIDTo = Guid.Empty; + worldlink.TypeTo = ObjectType.NotIdentifiedEnum; + _worldLinkService.Replace(worldlink); + } + if (worldlinkinfo.Length > 1) + { + result += ", but removed object was referenced in " + worldlinkinfo + " and removed there as well"; + } + return (count > 0) ? new ObjectResult(result) : StatusCode(404, "Not found, could not find UUID in database."); + } + + /// + /// Find a World Anchor by its UUID. + /// + public override IActionResult GetWorldAnchorById([FromRoute(Name = "worldAnchorUUID")][Required] Guid worldAnchorUUID, [FromHeader] string token) + { + WorldAnchor myworldanchor = _worldAnchorService.Get(worldAnchorUUID); + return (null != myworldanchor) ? new ObjectResult(myworldanchor) : StatusCode(404, "Not found, could not find UUID in database."); + } + + /// + /// Return all the World Anchors. + /// + public override IActionResult GetWorldAnchors([FromHeader] string token) + { + List worldanchorlist = _worldAnchorService.Get(); + return new ObjectResult(worldanchorlist); + } + + + + /// + /// Modify a World Anchor. + /// + public override IActionResult ModifyWorldAnchor([FromBody] WorldAnchor worldAnchor, [FromHeader] string token) + { + long count = _worldAnchorService.Replace(worldAnchor); + if (count == 0) + { + return StatusCode(404, "Not found, could not find UUID in database."); + } + else + { + return StatusCode(200, worldAnchor.UUID.ToString()); + } + } + + + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs new file mode 100644 index 0000000..fbd119f --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs @@ -0,0 +1,207 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +/* + * World Storage API + * + * API ensuring interoperability between an authoring tool and a World Storage service + * + * The version of the OpenAPI document: 1.0.0 + * + * Generated by: https://openapi-generator.tech + */ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using Swashbuckle.AspNetCore.Annotations; +using Swashbuckle.AspNetCore.SwaggerGen; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Attributes; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using ETSI.ARF.OpenAPI.WorldStorage.Services; +using MongoDB.Driver; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers +{ + /// + /// + /// + [ApiController] + public class WorldLinksApiControllerImpl : WorldLinksApiController + { + private readonly TrackableService _trackableService; + private readonly WorldAnchorService _worldAnchorService; + private readonly WorldLinkService _worldLinkService; + + /// + /// + /// + public WorldLinksApiControllerImpl(WorldLinkService worldLinkService, TrackableService trackableService, WorldAnchorService worldAnchorService) + { + _worldLinkService = worldLinkService; + _trackableService = trackableService; + _worldAnchorService = worldAnchorService; + } + + /// + /// Create a World Link between elements (world anchors and/or trackables). + /// + public override IActionResult AddWorldLink([FromBody] WorldLink worldLink, [FromHeader] string token) + { + if (String.IsNullOrEmpty(worldLink.UUID.ToString())) + { + worldLink.UUID = Guid.NewGuid(); + } + try + { + WorldLink myworldlink = _worldLinkService.Create(worldLink); + return StatusCode(200, myworldlink.UUID.ToString()); + } + catch (Exception e) + { + return StatusCode(400, e.Message); + } + } + + /// + /// Delete a World Link. + /// + public override IActionResult DeleteWorldLink([FromRoute(Name = "worldLinkUUID")][Required] Guid worldLinkUUID, [FromHeader] string token) + { + long count = _worldLinkService.Remove(worldLinkUUID); + return (count > 0) ? new ObjectResult("ok") : StatusCode(404, "Not found, could not find UUID in database."); + } + + + /// + /// Find a World Link by its UUID. + /// + public override IActionResult GetWorldLinkById([FromRoute(Name = "worldLinkUUID")][Required] Guid worldLinkUUID, [FromHeader] string token) + { + WorldLink myworldlink = _worldLinkService.Get(worldLinkUUID); + if (null != myworldlink) + { + // check TypeFrom + if (myworldlink.TypeFrom == ObjectType.TrackableEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + // check TypeTo + if (myworldlink.TypeTo == ObjectType.TrackableEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + } + return (null != myworldlink) ? new ObjectResult(myworldlink) : StatusCode(404, "Not found, could not find UUID in database."); + } + + /// + /// Return all World Links. + /// + public override IActionResult GetWorldLinks([FromHeader] string token) + { + List worldlinklist = _worldLinkService.Get(); + foreach (WorldLink myworldlink in worldlinklist) + { + // check TypeFrom + if (myworldlink.TypeFrom == ObjectType.TrackableEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + // check TypeTo + if (myworldlink.TypeTo == ObjectType.TrackableEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + } + return new ObjectResult(worldlinklist); + } + + + + /// + /// Modify a World Link. + /// + public override IActionResult ModifyWorldLink([FromBody] WorldLink worldLink, [FromHeader] string token) + { + long count = _worldLinkService.Replace(worldLink); + if (count == 0) + { + return StatusCode(404, "Not found, could not find UUID in database."); + } + else + { + return StatusCode(200, worldLink.UUID.ToString()); + } + } + } +} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/IModels.cs similarity index 91% rename from server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs rename to server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/IModels.cs index c6660a8..0c033f8 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Models/IModels.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/IModels.cs @@ -31,9 +31,8 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Models public string Name { get; set; } /// - /// GUID is managed by EConoM system + /// UUID is managed by ARF /// - public Guid GUID { get; set; } - + public Guid UUID { get; set; } } } \ No newline at end of file diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/TrackableExt.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/TrackableExt.cs new file mode 100644 index 0000000..a6561a1 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/TrackableExt.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using System.Text; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Converters; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Models +{ + /// + /// An element representing an xxx in the MongoDB. + /// To ignore entries see: https://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/#ignoring-extra-elements + /// + [BsonIgnoreExtraElements] + public partial class Trackable : IModels + { + /// + /// If an element from the DB is not existing in the class + /// we can receive the info which elements + /// + [BsonExtraElements] + public BsonDocument CatchAll { get; set; } + + /// + /// ID is managed by mongo + /// + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public ObjectId _id; + + /// + /// Get mongo ID + /// + //[BsonIgnore] - don't ignore, so mongo replace can use it! + public ObjectId _mongoID { get => _id; set => _id = value; } + } +} \ No newline at end of file diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldAnchorExt.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldAnchorExt.cs new file mode 100644 index 0000000..d534fb7 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldAnchorExt.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using System.Text; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Converters; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Models +{ + /// + /// An element representing an xxx in the MongoDB. + /// To ignore entries see: https://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/#ignoring-extra-elements + /// + [BsonIgnoreExtraElements] + public partial class WorldAnchor : IModels + { + /// + /// If an element from the DB is not existing in the class + /// we can receive the info which elements + /// + [BsonExtraElements] + public BsonDocument CatchAll { get; set; } + + /// + /// ID is managed by mongo + /// + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public ObjectId _id; + + /// + /// Get mongo ID + /// + //[BsonIgnore] - don't ignore, so mongo replace can use it! + public ObjectId _mongoID { get => _id; set => _id = value; } + } +} \ No newline at end of file diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldLinksExt.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldLinksExt.cs new file mode 100644 index 0000000..6ae0022 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/WorldLinksExt.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; +using System.Text; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using ETSI.ARF.OpenAPI.WorldStorage.Converters; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace ETSI.ARF.OpenAPI.WorldStorage.Models +{ + /// + /// An element representing an xxx in the MongoDB. + /// To ignore entries see: https://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/#ignoring-extra-elements + /// + [BsonIgnoreExtraElements] + public partial class WorldLink : IModels + { + /// + /// Name, if needed + /// + [BsonIgnore] + public string Name { get; set; } + + /// + /// If an element from the DB is not existing in the class + /// we can receive the info which elements + /// + [BsonExtraElements] + public BsonDocument CatchAll { get; set; } + + /// + /// ID is managed by mongo + /// + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public ObjectId _id; + + /// + /// Get mongo ID + /// + //[BsonIgnore] - don't ignore, so mongo replace can use it! + public ObjectId _mongoID { get => _id; set => _id = value; } + } +} \ No newline at end of file diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs index 2e1e8cd..4f9da56 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs @@ -49,12 +49,12 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services // to do? } - // Check manually if a GUID document already exists! - public bool CheckIfExist(Guid GUID) + // Check manually if a UUID document already exists! + public bool CheckIfExist(Guid UUID) { foreach (var obj in Get()) { - if (((Models.IModels)obj).GUID == GUID) return true; + if (((Models.IModels)obj).UUID == UUID) return true; } return false; } @@ -67,7 +67,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services private void _print(T obj) { - Console.WriteLine("[Mongo Server] User # " + ((Models.IModels)obj).GUID); + Console.WriteLine("[Mongo Server] User # " + ((Models.IModels)obj).UUID); } public void PrintAll() @@ -79,8 +79,8 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services public T Create(T obj) { - // Test first if GUID doesn't exist - bool exist = CheckIfExist(((Models.IModels)obj).GUID); + // Test first if UUID doesn't exist + bool exist = CheckIfExist(((Models.IModels)obj).UUID); if (!exist) { mongoCollection.InsertOne(obj); @@ -93,9 +93,6 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services // Get the current mongo _id of the object in the database // #region Get current mongo ID or object/document - private Guid _newObjGUID; - private T _currentObj; - private ObjectId _currentMongoID; private ObjectId getMongoIDFromName(string name) { var res = mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault(); @@ -103,31 +100,28 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services else return ((Models.IModels)res)._mongoID; } - private ObjectId getMongoIDFromGUID(Guid GUID) + private ObjectId getMongoIDFromUUID(Guid UUID) { - _newObjGUID = GUID; - _currentMongoID = ObjectId.Empty; + ObjectId _currentMongoID = ObjectId.Empty; var i = mongoCollection.Find(_ => true); - i.ForEachAsync(_compareAndRemember).Wait(); - return _currentMongoID; - } - - private void _compareAndRemember(T obj) - { - if (_currentMongoID != ObjectId.Empty) return; // take the first one - if (((Models.IModels)obj).GUID == _newObjGUID) + //i.ForEachAsync(_compareAndRemember).Wait(); + i.ForEachAsync(doc => { - _currentObj = obj; - _currentMongoID = ((Models.IModels)obj)._mongoID; + if (_currentMongoID != ObjectId.Empty) return; // take the first one + if (((Models.IModels)doc).UUID == UUID) + { + _currentMongoID = ((Models.IModels)doc)._mongoID; + } } + ).Wait(); + return _currentMongoID; } #endregion - //abstract public long Replace(T obj); - public long Replace(T obj) //=> assetCollection.ReplaceOne(asset => asset.GUID == GUID, obj); + public long Replace(T obj) //=> assetCollection.ReplaceOne(asset => asset.UUID == UUID, obj); { // Which mongo document? - ObjectId mongoID = getMongoIDFromGUID(((Models.IModels)obj).GUID); + ObjectId mongoID = getMongoIDFromUUID(((Models.IModels)obj).UUID); // Object was found, so replace it using the _id if (mongoID != ObjectId.Empty) @@ -138,14 +132,14 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services else return 0; } - public long Remove(T obj) => Remove(((Models.IModels)obj).GUID); + public long Remove(T obj) => Remove(((Models.IModels)obj).UUID); - public long Remove(Guid GUID) + public long Remove(Guid UUID) { - //return mongoCollection.DeleteOne(o => ((Models.IModels)o).GUID == GUID); - + //return mongoCollection.DeleteOne(o => ((Models.IModels)o).UUID == UUID); + // Which mongo document? - ObjectId mongoID = getMongoIDFromGUID(GUID); + ObjectId mongoID = getMongoIDFromUUID(UUID); // Object was found, so replace it using the _id if (mongoID != ObjectId.Empty) @@ -154,7 +148,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services return mongoCollection.DeleteOne(o => ((Models.IModels)o)._mongoID == mongoID).DeletedCount; } - else return 0; + else return 0; } // Return all documents @@ -163,16 +157,16 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services // Limit the result to the first n documents public List Get(int limit) => mongoCollection.Find(_ => true).Limit(limit).ToList(); - // Search manually the document with the id GUID + // Search manually the document with the id UUID public T Get(string name) => mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).FirstOrDefault(); - // Geht nicht! public override T Get(Guid GUID) => mongoCollection.Find(o => o.GUID == GUID).FirstOrDefault(); + // Geht nicht! public override T Get(Guid UUID) => mongoCollection.Find(o => o.UUID == UUID).FirstOrDefault(); // Work around: look in all elements if the GUIDs are equals - public T Get(Guid GUID) + public T Get(Guid UUID) { foreach (T obj in Get()) { - if (((Models.IModels)obj).GUID == GUID) return obj; + if (((Models.IModels)obj).UUID == UUID) return obj; } return default(T); } diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs index 197907f..6327b3d 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/DatabaseSettings.cs @@ -12,9 +12,9 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services string DatabaseName { get; set; } string MongoSrv { get; set; } string MongoPort { get; set; } - public string CollectionNameWorldLink { get; set; } public string CollectionNameTrackables { get; set; } - public string CollectionNameWorldAnchor { get; set; } + public string CollectionNameWorldAnchors { get; set; } + public string CollectionNameWorldLinks { get; set; } } public class DatabaseSettings : IDatabaseSettings @@ -23,9 +23,9 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services public string DatabaseName { get; set; } public string MongoSrv { get; set; } public string MongoPort { get; set; } - public string CollectionNameWorldLink { get; set; } public string CollectionNameTrackables { get; set; } - public string CollectionNameWorldAnchor { get; set; } + public string CollectionNameWorldAnchors { get; set; } + public string CollectionNameWorldLinks { get; set; } } } #pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element diff --git a/server/src/Org.OpenAPITools/Services/DatabaseSettings.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/TrackableService.cs similarity index 53% rename from server/src/Org.OpenAPITools/Services/DatabaseSettings.cs rename to server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/TrackableService.cs index 93f177d..c7601cb 100644 --- a/server/src/Org.OpenAPITools/Services/DatabaseSettings.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/TrackableService.cs @@ -22,24 +22,24 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using MongoDB.Driver; -namespace Org.OpenAPITools.Services +#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element +namespace ETSI.ARF.OpenAPI.WorldStorage.Services { - public class DatabaseSettings : IDatabaseSettings - { - public string CollectionNameWorldLink { get; set; } - public string CollectionNameTrackables { get; set; } - public string CollectionNameWorldAnchor { get; set; } - public string ConnectionString { get; set; } - public string DatabaseName { get; set; } - } - - public interface IDatabaseSettings - { - string CollectionNameWorldLink { get; set; } - string CollectionNameTrackables { get; set; } - string CollectionNameWorldAnchor { get; set; } - string ConnectionString { get; set; } - string DatabaseName { get; set; } - } + public class TrackableService : BaseService + { + /// + /// + /// + public TrackableService(IDatabaseSettings settings) : base(settings) + { + // Select the collection + mongoCollection = mongoDatabase.GetCollection(settings.CollectionNameTrackables); + } + } } +#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element + + diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldAnchorService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldAnchorService.cs new file mode 100644 index 0000000..2b50133 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldAnchorService.cs @@ -0,0 +1,44 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using MongoDB.Driver; + +#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element +namespace ETSI.ARF.OpenAPI.WorldStorage.Services +{ + public class WorldAnchorService : BaseService + { + /// + /// + /// + public WorldAnchorService(IDatabaseSettings settings) : base(settings) + { + // Select the collection + mongoCollection = mongoDatabase.GetCollection(settings.CollectionNameWorldAnchors); + } + } +} +#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element + diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldLinkService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldLinkService.cs new file mode 100644 index 0000000..dac8abd --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/WorldLinkService.cs @@ -0,0 +1,67 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using ETSI.ARF.OpenAPI.WorldStorage.Models; +using MongoDB.Driver; + +#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element +namespace ETSI.ARF.OpenAPI.WorldStorage.Services +{ + public class WorldLinkService : BaseService + { + /// + /// + /// + public WorldLinkService(IDatabaseSettings settings) : base(settings) + { + // Select the collection + mongoCollection = mongoDatabase.GetCollection(settings.CollectionNameWorldLinks); + } + + public List GetWorldLinkUUIDFrom(Guid UUIDFrom) + { + List res = new List(); + var i = mongoCollection.Find(_ => true); + i.ForEachAsync(doc => + { + if (doc.UUIDFrom == UUIDFrom) res.Add(doc); + } + ).Wait(); + return res; + } + + public List GetWorldLinkUUIDTo(Guid UUIDTo) + { + List res = new List(); + var i = mongoCollection.Find(_ => true); + i.ForEachAsync(doc => + { + if (doc.UUIDTo == UUIDTo) res.Add(doc); + } + ).Wait(); + return res; + } + } +} +#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs index a6299c1..af7fb23 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs @@ -43,7 +43,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage /// /// The API version. (how to read it from the yaml?) /// - static public string apiVersion = "1.0.0"; + static public string apiVersion = "1.1.0"; /// /// Demo access key @@ -99,9 +99,11 @@ namespace ETSI.ARF.OpenAPI.WorldStorage // BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)); //BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; + var s = services.AddSingleton(sp => sp.GetRequiredService>().Value); - //services.AddSingleton(); - //services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); // Add framework services. services diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json deleted file mode 100644 index def9159..0000000 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/_appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json index 7b6341f..558708e 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json @@ -2,12 +2,12 @@ "DatabaseSettings": { "Description" : "Version for IIS", "LocalDataPath": ".\\wwwroot\\dataspace\\data", - "MongoSrv": "localhost", - "MongoPort": "27017", + "MongoSrv": "192-168-020-029.fe.hhi.de", + "MongoPort": "27037", "DatabaseName": "WorldStorageAPI", - "CollectionNameWorldLink": "WorldLink", + "CollectionNameWorldLinks": "WorldLinks", "CollectionNameTrackables": "Trackables", - "CollectionNameWorldAnchor": "WorldAnchor" + "CollectionNameWorldAnchors": "WorldAnchors" }, "Logging": { "LogLevel": { -- GitLab From 3510dab48ee5a7f6e8dfb865be208e13e40dd27d Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Fri, 1 Mar 2024 12:03:59 +0100 Subject: [PATCH 05/11] New implementation of the World Storage IIS Server (STF620 endpoints only). --- openapi | 2 +- readme.md | 25 ++++++++++++++++++- .../ControllersImpl/TrackablesImpl.cs | 7 +++--- .../ControllersImpl/WorldAnchorsImpl.cs | 7 +++--- .../ControllersImpl/WorldLinksImpl.cs | 14 +++++++---- .../ETSI-ARF/Services/BaseService.cs | 8 +++++- .../appsettings.json | 2 +- 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/openapi b/openapi index 08aa3ca..57adeb4 160000 --- a/openapi +++ b/openapi @@ -1 +1 @@ -Subproject commit 08aa3ca82b2f3d78ee765df3e0d9046b3ab81ba1 +Subproject commit 57adeb471026ccc88074889aefbe68ef692cb0ca diff --git a/readme.md b/readme.md index 48846b3..6bac909 100644 --- a/readme.md +++ b/readme.md @@ -23,9 +23,11 @@ It includes description and code for a fully functional server with MongoDB inte |:-:|:--------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | 📂 | openapi | A git submodule (ForgeETSI ) pointing to the repo containing the API specification file | | 📂 | server | The folder where the library code will be generated, the openapi generator is set to not overwrite some files used to generate and initialiue the ASP.Net server system | -| 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | + | 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage | This is the location where the ASP.Net code will be generated | | 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF | THis folder contains codes implementating the REST end-paths for the different objects in API | +| 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | +| 📂 | server\worldstorage\src\ETSI.ARF.OpenAPI.WorldStorage\appsettings.json | Parameter for accessing the MongoDB server from the ASP.NET services | This file contains the MongoDB server IP and optional port number, name of the World Storage database and their collections. | ## Requirements @@ -124,6 +126,27 @@ If you don't have a MongoDB, follow the instructions in `readme.md` in `server/p ...and put MongoDB in folder `server/programs/MongoDB` (download MongoDB as zip-file from https://www.mongodb.com/try/download/community and unzip the file into this directory, so that the bin-directory is in this folder). +To setup MongoDB in the IIS webserver, adjust the parameters in the file `appsettings.json`. Default values for the databes an collections are: + + "DatabaseName": "WorldStorageAPI", + "CollectionNameWorldLinks": "WorldLinks", + "CollectionNameTrackables": "Trackables", + "CollectionNameWorldAnchors": "WorldAnchors" + +Set the correct server IP/adress and port number (if there is one). Use the network setup as you define in the Docker-Compose yaml file, e.g. +``` + ports: + - 27037:27017 // mapping, for accessing the MongoDB from outside + - 27038:27018 + networks: + vpcbr: + ipv4_address: 172.24.30.101 // or whatever you want +``` +Server settings: + + "MongoSrv": "172.24.30.101", // same as defined in the yaml file + "MongoPort": "27017", // internal docker port + ## How to dump database Execute the following command in docker: ``` diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs index cc3064a..9d8d06b 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs @@ -51,15 +51,13 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers public class TrackablesApiControllerImpl : TrackablesApiController { private readonly TrackableService _trackableService; - private readonly WorldLinkService _worldLinkService; /// /// /// - public TrackablesApiControllerImpl(TrackableService trackableService, WorldLinkService worldLinkService) + public TrackablesApiControllerImpl(TrackableService trackableService) { _trackableService = trackableService; - _worldLinkService = worldLinkService; } @@ -88,6 +86,9 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers /// public override IActionResult DeleteTrackable([FromRoute(Name = "trackableUUID")][Required] Guid trackableUUID, [FromHeader] string token) { + // Access other service(s) + WorldLinkService _worldLinkService = WorldLinkService.Singleton as WorldLinkService; + long count = _trackableService.Remove(trackableUUID); // check, if used in WorldLink string result = "ok"; diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs index 7acf41a..97189a0 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs @@ -51,15 +51,13 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers public class WorldAnchorsApiControllerImpl : WorldAnchorsApiController { private readonly WorldAnchorService _worldAnchorService; - private readonly WorldLinkService _worldLinkService; /// /// /// - public WorldAnchorsApiControllerImpl(WorldAnchorService worldAnchorService, WorldLinkService worldLinkService) + public WorldAnchorsApiControllerImpl(WorldAnchorService worldAnchorService) { _worldAnchorService = worldAnchorService; - _worldLinkService = worldLinkService; } @@ -88,6 +86,9 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers /// public override IActionResult DeleteWorldAnchor([FromRoute(Name = "worldAnchorUUID")][Required] Guid worldAnchorUUID, [FromHeader] string token) { + // Access other service(s) + WorldLinkService _worldLinkService = WorldLinkService.Singleton as WorldLinkService; + long count = _worldAnchorService.Remove(worldAnchorUUID); // check, if used in WorldLink string result = "ok"; diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs index fbd119f..9bbb362 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs @@ -50,18 +50,14 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers [ApiController] public class WorldLinksApiControllerImpl : WorldLinksApiController { - private readonly TrackableService _trackableService; - private readonly WorldAnchorService _worldAnchorService; private readonly WorldLinkService _worldLinkService; /// /// /// - public WorldLinksApiControllerImpl(WorldLinkService worldLinkService, TrackableService trackableService, WorldAnchorService worldAnchorService) + public WorldLinksApiControllerImpl(WorldLinkService worldLinkService) { _worldLinkService = worldLinkService; - _trackableService = trackableService; - _worldAnchorService = worldAnchorService; } /// @@ -99,6 +95,10 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers /// public override IActionResult GetWorldLinkById([FromRoute(Name = "worldLinkUUID")][Required] Guid worldLinkUUID, [FromHeader] string token) { + // Access other service(s) + TrackableService _trackableService = TrackableService.Singleton as TrackableService; + WorldAnchorService _worldAnchorService = WorldAnchorService.Singleton as WorldAnchorService; + WorldLink myworldlink = _worldLinkService.Get(worldLinkUUID); if (null != myworldlink) { @@ -145,6 +145,10 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers /// public override IActionResult GetWorldLinks([FromHeader] string token) { + // Access other service(s) + TrackableService _trackableService = TrackableService.Singleton as TrackableService; + WorldAnchorService _worldAnchorService = WorldAnchorService.Singleton as WorldAnchorService; + List worldlinklist = _worldLinkService.Get(); foreach (WorldLink myworldlink in worldlinklist) { diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs index 4f9da56..90e909e 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/Services/BaseService.cs @@ -32,7 +32,13 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Services public BaseService(IDatabaseSettings settings) { // Store the singleton - if (_singleton != null) throw new Exception("Service can only be instantiated one time!"); + if (_singleton != null) + { + string msg = "World Storage API: Service for '" + settings.CollectionNameTrackables + "' can only be instantiated one time!"; + Console.WriteLine(msg); + return; + //throw new Exception(msg); + } else _singleton = this; _settings = settings; diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json index 558708e..f740468 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json @@ -1,6 +1,6 @@ { "DatabaseSettings": { - "Description" : "Version for IIS", + "Description" : "Version for Visual Studio", "LocalDataPath": ".\\wwwroot\\dataspace\\data", "MongoSrv": "192-168-020-029.fe.hhi.de", "MongoPort": "27037", -- GitLab From 68d694b7033563df204b430aba7580a96797b005 Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Fri, 1 Mar 2024 12:07:33 +0100 Subject: [PATCH 06/11] syntax check --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 6bac909..1b10996 100644 --- a/readme.md +++ b/readme.md @@ -25,9 +25,9 @@ It includes description and code for a fully functional server with MongoDB inte | 📂 | server | The folder where the library code will be generated, the openapi generator is set to not overwrite some files used to generate and initialiue the ASP.Net server system | | 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage | This is the location where the ASP.Net code will be generated | -| 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF | THis folder contains codes implementating the REST end-paths for the different objects in API | +| 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF | This folder contains codes implementating the REST end-paths for the different objects in API | | 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | -| 📂 | server\worldstorage\src\ETSI.ARF.OpenAPI.WorldStorage\appsettings.json | Parameter for accessing the MongoDB server from the ASP.NET services | This file contains the MongoDB server IP and optional port number, name of the World Storage database and their collections. | +| 📂 | server\worldstorage\src\ETSI.ARF.OpenAPI.WorldStorage\appsettings.json | Parameter for accessing the MongoDB server from the ASP.NET services. This file contains the MongoDB server IP and optional port number, name of the World Storage database and their collections. | ## Requirements -- GitLab From 92ec7b14e7a06d28b63bc955b605f7ba4578de0a Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Fri, 1 Mar 2024 12:11:13 +0100 Subject: [PATCH 07/11] syntax check --- readme.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 1b10996..8ee30a2 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,6 @@ It includes description and code for a fully functional server with MongoDB inte |:-:|:--------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | 📂 | openapi | A git submodule (ForgeETSI ) pointing to the repo containing the API specification file | | 📂 | server | The folder where the library code will be generated, the openapi generator is set to not overwrite some files used to generate and initialiue the ASP.Net server system | - | 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage | This is the location where the ASP.Net code will be generated | | 📂 | server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF | This folder contains codes implementating the REST end-paths for the different objects in API | | 📂 | server/programs/MongoDB | This folder contains the MongoDB service. The World Storage database should be created or imported in a folder of your choice which path has to be editied in the .bat file | @@ -55,7 +54,7 @@ Open `NuGet Package Manager` and add `MongoDB.Driver`. ### File adaptations Change version number in all files if a new version is provided. -### Custom folder (new) +## 📂 Custom folders (new) All custom files are now in the folder 'ETSI-ARF'. Nothing to do adapt manually after generation. But you have to provide the implementation of new endpoints because they are now directly declared as abstract (default). The folder contains following subfolders: @@ -63,7 +62,7 @@ The folder contains following subfolders: `ModelsExt` `Services` -### Folder 'ControllersImp' +### 📂 Folder 'ControllersImp' The modules in this folder implement the endpoints. Compare files folder in "`ETSI-ARF/ControllersImpl`" with the corresponding files in "`Controllers`" and implement if necessary the new methods. @@ -95,7 +94,7 @@ public TrackablesApiControllerImpl(TrackableService trackableService) Implement endpoint code using the appropriate MongoDB methods of the corresponding classes from the folder `Services` (which you may be have to create). -### Folder `ModelsExt` +### 📂 Folder `ModelsExt` The modules inside this folder are for extensions of the generated API data structures. Add all the classes to be stored in the database (i.e. `TrackableExt.cs`, `WorldAnchorExt.cs`, `WorldLinkExt.cs`) inherited from `IModels`. (definition of the extra UUID): ``` using MongoDB.Bson; @@ -113,12 +112,12 @@ If some members won't be saved in the MongoDB then use this keyword: [BsonIgnore] ``` -### Folder `Services` +### 📂 Folder `Services` The folder `Services` is for handling the data with the MongoDB. It should contain one common class with the DatabaseSettings (`DatabaseSettings.cs`) and one with the database-access-methods (create, get, update, remove) for each API. If some are missing create them like the ones you find there. Be aware to add the reference to these in the file `startup.cs` in this case. The naming in the DatabaseSettings is the same as defined in `appsettings.json`, which you have to extend when creating new classes in this folder. Change `appsettings.json` in the folder `docker` accordingly. Make sure that the ConnectionString for the database contains the correct IP address as specified in `docker-compose.yml`. -## Extra folder `wwwroot` +## 📂 Extra folder `wwwroot` Add in `openapi-original.json` in section `servers` the urls of the servers you want to use with swagger-ui # MongoDB -- GitLab From 0f1afc2615bd0e50169d23d882f521bad6a941fb Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Mon, 4 Mar 2024 15:14:55 +0100 Subject: [PATCH 08/11] Now, the new config file (.json) has to be used. --- openapitools.json | 15 ++++++++++++++- readme.md | 30 ++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/openapitools.json b/openapitools.json index 3b40e47..05dd985 100644 --- a/openapitools.json +++ b/openapitools.json @@ -2,6 +2,19 @@ "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", "spaces": 2, "generator-cli": { - "version": "5.3.0" + "version": "5.3.0", + "generators":{ + "v1.1": { + "generatorName": "aspnetcore", + "output": "./server/worldstorage", + "inputSpec": "./openapi/API/worldstorage/worldstorageopenapi.yaml", + "additionalProperties": { + "aspnetCoreVersion": "5.0", + "packageName": "ETSI.ARF.OpenAPI.WorldStorage", + "operationModifier": "abstract", + "classModifier": "abstract" + } + } + } } } diff --git a/readme.md b/readme.md index 8ee30a2..f16bded 100644 --- a/readme.md +++ b/readme.md @@ -38,12 +38,38 @@ What you need: # Code Generation -We provided the file `.openapi-generator-ignore` in `server`, which prevents openapi-generator to override some adapted files. +We provide the file `.openapi-generator-ignore` in `server`, which prevents openapi-generator to override some adapted files. ## Auto-generate server code + +Use/define following setup for the config file `openapitools.json`: + +``` +{ + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "5.3.0", + "generators":{ + "v1.1": { + "generatorName": "aspnetcore", + "output": "./server/worldstorage", + "inputSpec": "./openapi/API/worldstorage/worldstorageopenapi.yaml", + "additionalProperties": { + "aspnetCoreVersion": "5.0", + "packageName": "ETSI.ARF.OpenAPI.WorldStorage", + "operationModifier": "abstract", + "classModifier": "abstract" + } + } + } + } +} +``` + Open a command shell and execute: ``` - npx openapi-generator-cli generate -i openapi/API/worldstorage/worldstorageopenapi.yaml --additional-properties aspnetCoreVersion=5.0,packageName=ETSI.ARF.OpenAPI.WorldStorage,operationModifier=abstract,classModifier=abstract -g aspnetcore -o server/worldstorage + npx openapi-generator-cli generate ``` Open the solution `ETSI.ARF.OpenAPI.WorldStorage.sln` (folder `server/worldstorage`) in Visual Studio: -- GitLab From ab569b2135b8d1e1422c3366277df2c6eb073c37 Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Mon, 25 Mar 2024 13:14:09 +0100 Subject: [PATCH 09/11] Changed api folder name. --- .gitmodules | 9 +++------ openapi | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) delete mode 160000 openapi diff --git a/.gitmodules b/.gitmodules index 54f9b63..12c8ab4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,4 @@ -[submodule "arf005"] - path = arf005 - url = git@forge.etsi.org:arf/arf005.git - branch = develop -[submodule "openapi"] - path = openapi +[submodule "ARFOpenAPI"] + path = ARFOpenAPI url = https://forge.etsi.org/rep/arf/openapi.git + branch = master \ No newline at end of file diff --git a/openapi b/openapi deleted file mode 160000 index 57adeb4..0000000 --- a/openapi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 57adeb471026ccc88074889aefbe68ef692cb0ca -- GitLab From d22f891ca3e34c9e20c9f8a73324affdf8885021 Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Mon, 25 Mar 2024 13:20:46 +0100 Subject: [PATCH 10/11] Fixed submodule name (renamed for consistency to opanapi) --- .gitmodules | 4 ++-- openapi | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 160000 openapi diff --git a/.gitmodules b/.gitmodules index 12c8ab4..455ab71 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "ARFOpenAPI"] - path = ARFOpenAPI +[submodule "openapi"] + path = openapi url = https://forge.etsi.org/rep/arf/openapi.git branch = master \ No newline at end of file diff --git a/openapi b/openapi new file mode 160000 index 0000000..57adeb4 --- /dev/null +++ b/openapi @@ -0,0 +1 @@ +Subproject commit 57adeb471026ccc88074889aefbe68ef692cb0ca -- GitLab From 777b58a920f9c13818b5ef02bcee4965cf4c5c7a Mon Sep 17 00:00:00 2001 From: Sylvain Renault Date: Wed, 10 Apr 2024 17:42:22 +0200 Subject: [PATCH 11/11] Services are intitalized on server startup. Creating an object with a given UUID now get an 409 error if the id is already existing in the database. --- openapi | 2 +- .../ControllersImpl/TrackablesImpl.cs | 10 +++-- .../ControllersImpl/WorldAnchorsImpl.cs | 10 +++-- .../ControllersImpl/WorldLinksImpl.cs | 38 ++++++++++--------- .../ETSI.ARF.OpenAPI.WorldStorage/Startup.cs | 13 +++++-- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/openapi b/openapi index 57adeb4..84f8163 160000 --- a/openapi +++ b/openapi @@ -1 +1 @@ -Subproject commit 57adeb471026ccc88074889aefbe68ef692cb0ca +Subproject commit 84f816367c469b590cb2db47a4bb1b06b56729f9 diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs index 9d8d06b..5845b10 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs @@ -73,7 +73,11 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers try { Trackable mytrackable = _trackableService.Create(trackable); - return StatusCode(200, mytrackable.UUID.ToString()); + if (mytrackable == null) + { + return StatusCode(409, "UUID already existing!"); + } + else return StatusCode(200, mytrackable.UUID.ToString()); } catch (Exception e) { @@ -100,7 +104,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers { worldlinkinfo += worldlink.UUID.ToString() + "; "; worldlink.UUIDFrom = Guid.Empty; - worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + worldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; _worldLinkService.Replace(worldlink); } @@ -110,7 +114,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers { worldlinkinfo += worldlink.UUID.ToString() + "; "; worldlink.UUIDTo = Guid.Empty; - worldlink.TypeTo = ObjectType.NotIdentifiedEnum; + worldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; _worldLinkService.Replace(worldlink); } if (worldlinkinfo.Length > 1) diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs index 97189a0..8d5e48b 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs @@ -73,7 +73,11 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers try { WorldAnchor myworldanchor = _worldAnchorService.Create(worldAnchor); - return StatusCode(200, myworldanchor.UUID.ToString()); + if (myworldanchor == null) + { + return StatusCode(409, "UUID alread exexisting!"); + } + else return StatusCode(200, myworldanchor.UUID.ToString()); } catch (Exception e) { @@ -100,7 +104,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers { worldlinkinfo += worldlink.UUID.ToString() + "; "; worldlink.UUIDFrom = Guid.Empty; - worldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + worldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; _worldLinkService.Replace(worldlink); } @@ -110,7 +114,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers { worldlinkinfo += worldlink.UUID.ToString() + "; "; worldlink.UUIDTo = Guid.Empty; - worldlink.TypeTo = ObjectType.NotIdentifiedEnum; + worldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; _worldLinkService.Replace(worldlink); } if (worldlinkinfo.Length > 1) diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs index 9bbb362..cd5da8a 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs @@ -72,7 +72,11 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers try { WorldLink myworldlink = _worldLinkService.Create(worldLink); - return StatusCode(200, myworldlink.UUID.ToString()); + if (myworldlink == null) + { + return StatusCode(409, "UUID already existing!"); + } + else return StatusCode(200, myworldlink.UUID.ToString()); } catch (Exception e) { @@ -103,36 +107,36 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers if (null != myworldlink) { // check TypeFrom - if (myworldlink.TypeFrom == ObjectType.TrackableEnum) + if (myworldlink.TypeFrom == TypeWorldStorage.TRACKABLEEnum) { if (null == _trackableService.Get(myworldlink.UUIDFrom)) { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDFrom = Guid.Empty; } } - else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) + else if (myworldlink.TypeFrom == TypeWorldStorage.ANCHOREnum) { if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDFrom = Guid.Empty; } } // check TypeTo - if (myworldlink.TypeTo == ObjectType.TrackableEnum) + if (myworldlink.TypeTo == TypeWorldStorage.TRACKABLEEnum) { if (null == _trackableService.Get(myworldlink.UUIDTo)) { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDTo = Guid.Empty; } } - else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) + else if (myworldlink.TypeTo == TypeWorldStorage.ANCHOREnum) { if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDTo = Guid.Empty; } } @@ -153,36 +157,36 @@ namespace ETSI.ARF.OpenAPI.WorldStorage.Controllers foreach (WorldLink myworldlink in worldlinklist) { // check TypeFrom - if (myworldlink.TypeFrom == ObjectType.TrackableEnum) + if (myworldlink.TypeFrom == TypeWorldStorage.TRACKABLEEnum) { if (null == _trackableService.Get(myworldlink.UUIDFrom)) { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDFrom = Guid.Empty; } } - else if (myworldlink.TypeFrom == ObjectType.WorldAnchorEnum) + else if (myworldlink.TypeFrom == TypeWorldStorage.ANCHOREnum) { if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) { - myworldlink.TypeFrom = ObjectType.NotIdentifiedEnum; + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDFrom = Guid.Empty; } } // check TypeTo - if (myworldlink.TypeTo == ObjectType.TrackableEnum) + if (myworldlink.TypeTo == TypeWorldStorage.TRACKABLEEnum) { if (null == _trackableService.Get(myworldlink.UUIDTo)) { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDTo = Guid.Empty; } } - else if (myworldlink.TypeTo == ObjectType.WorldAnchorEnum) + else if (myworldlink.TypeTo == TypeWorldStorage.ANCHOREnum) { if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) { - myworldlink.TypeTo = ObjectType.NotIdentifiedEnum; + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; myworldlink.UUIDTo = Guid.Empty; } } diff --git a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs index af7fb23..2978f0a 100644 --- a/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs @@ -92,8 +92,8 @@ namespace ETSI.ARF.OpenAPI.WorldStorage // // appsetting.json - requires using Microsoft.Extensions.Options - services.Configure(Configuration.GetSection(nameof(DatabaseSettings))); - + IServiceCollection c = services.Configure(Configuration.GetSection(nameof(DatabaseSettings))); + // // MongoDB // @@ -104,7 +104,7 @@ namespace ETSI.ARF.OpenAPI.WorldStorage services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - + // Add framework services. services // Don't need the full MVC stack for an API, see https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ @@ -160,6 +160,13 @@ namespace ETSI.ARF.OpenAPI.WorldStorage /// public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + // + // Initialize all ARF services + // + app.ApplicationServices.GetRequiredService(); + app.ApplicationServices.GetRequiredService(); + app.ApplicationServices.GetRequiredService(); + if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); -- GitLab