diff --git a/.gitignore b/.gitignore index 1ade888129707fa0cd8bd18bc1c0ba23ac113ce2..45d2095cdb31cf0937596e088eea358648b4bccd 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,25 +25,26 @@ server/programs/MongoDB/ !server/programs/MongoDB/readme.md #generated readme -server/README.md +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/ - -# generated project-files -*.csproj +Models +Controllers/ # generated Program.cs -Program.cs +#Program.cs # backup-files *.bak diff --git a/.gitmodules b/.gitmodules index 120fcda39cfee4122d0a409175f301b4a5405dda..455ab71b55998fb287f525e89da7ba82c44b6034 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "arf005"] - path = arf005 - url = git@forge.etsi.org:arf/arf005.git - branch = develop \ No newline at end of file +[submodule "openapi"] + path = openapi + url = https://forge.etsi.org/rep/arf/openapi.git + branch = master \ No newline at end of file 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 cbd23cf64baafbfa18079cf451ee244ab18af239..38a29adafc14ce78675a6e1e9d59359e5eaf3b8d 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 533b9d3198b772c7b628b0ab0e0a144b89966b46..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..ef7ec22c27c2b9398e152f0e1807333decda86db --- /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 0000000000000000000000000000000000000000..81eda89a647ab99a76ade58d3594e5abba9f2b22 --- /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 0000000000000000000000000000000000000000..0f23eca4742c5af318b6f37041442e46cb8c9a9a --- /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 0000000000000000000000000000000000000000..84f816367c469b590cb2db47a4bb1b06b56729f9 --- /dev/null +++ b/openapi @@ -0,0 +1 @@ +Subproject commit 84f816367c469b590cb2db47a4bb1b06b56729f9 diff --git a/openapitools.json b/openapitools.json index 3b40e47a45fd988f38e0b885958ceb2cac4a6201..05dd985129cded81e6cebeacd3658b5ddee66770 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 bc84c31f94b24bf5d6c345bfe0c5b9b1505bf356..f16bded3ee0adbd4d405df3853e08c551277c4d6 100644 --- a/readme.md +++ b/readme.md @@ -1,65 +1,127 @@ -# 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 - 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. It includes description and code for a fully functional server with MongoDB integration. -# Prerequisites +## Repo Content + +| | 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/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 + 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 -# 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. +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: ``` - openapi-generator-cli generate -i arf005\API\openapi.yaml -g aspnetcore -o server + npx openapi-generator-cli generate ``` -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: +## 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`: -Change "`public class`" to "`public abstract class`". +## 📂 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). -Compare files folder in "`ControllersImpl`" with the corresponding files in "`Controllers`" and adapt if necessary. +The folder contains following subfolders: +`ControllersImpl` +`ModelsExt` +`Services` -Methods should be the same with "`override`" instead of "`virtual`". +### 📂 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. -#### - if 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`) +Methods should be the same with "`override`" instead of "`abstract`". -..and replace `virtual` by `override` with all methods. +--- +#### If some files are missing (and only then!) Add ``` - using Org.OpenAPITools.Services; using MongoDB.Driver; ``` -Add a private readonly service class variable like in the already existing files. +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. +``` +public TrackablesApiControllerImpl(TrackableService trackableService) +{ + _trackableService = trackableService; + // etc. +} +``` -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 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`) : +### 📂 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; @@ -71,12 +133,17 @@ and at the value that is to become the MongoDB ID, add: [BsonRepresentation(BsonType.String)] ``` -### 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. +If some members won't be saved in the MongoDB then use this keyword: +``` +[BsonIgnore] +``` + +### 📂 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`. -### 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 @@ -84,6 +151,38 @@ 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: +``` + 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. @@ -91,38 +190,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`: +## How to stop +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** -``` \ No newline at end of file diff --git a/server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs b/server/src/Org.OpenAPITools/ControllersImpl/DefaultApiImpl.cs deleted file mode 100644 index b3d314ff0f22c2f1804ed5d050e20d151cd512c1..0000000000000000000000000000000000000000 --- 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 39ded8d709184b320509977b0372846c83db7979..0000000000000000000000000000000000000000 --- 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 9bb4100ea89d2d443e1234692ceebda2d78de752..0000000000000000000000000000000000000000 --- 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 0cb2b03232c04e7710169afe697b7b9a994733c3..0000000000000000000000000000000000000000 --- 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 267d1dfaaaba2df754d93ddc9cf2e2171f82d899..0000000000000000000000000000000000000000 --- 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 a115449919516309400d5ee19284e926f920c512..0000000000000000000000000000000000000000 --- 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 8a6e7c6974526a0ef332c02d0965470ecca7206c..0000000000000000000000000000000000000000 --- 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 073c59724eb6cb8c966ab2a1a3f003b31e768f7f..0000000000000000000000000000000000000000 --- 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 a3ee3471a19b486cbdfbefaa341ce4933f51744b..0000000000000000000000000000000000000000 --- 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 aebd1bbadc56a6c987a8359d0c6ffc87d5760f89..0000000000000000000000000000000000000000 --- 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 4bf996377154112c6c94313165f9d8123b2a1395..0000000000000000000000000000000000000000 --- 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 28066ba66cf25710db88eac58e4066184f67bd0c..0000000000000000000000000000000000000000 --- 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/worldstorage/.openapi-generator-ignore b/server/worldstorage/.openapi-generator-ignore new file mode 100644 index 0000000000000000000000000000000000000000..38a29adafc14ce78675a6e1e9d59359e5eaf3b8d --- /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 0000000000000000000000000000000000000000..1d802b381d537ef7a107138148f635129f6a5e42 --- /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/ControllersImpl/DefaultImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/DefaultImpl.cs new file mode 100644 index 0000000000000000000000000000000000000000..ea5c39ba95d6d969b9f6cb1643364bed6df7d7be --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/DefaultImpl.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 DefaultApiControllerImpl : 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.1.0"; + 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/ControllersImpl/TrackablesImpl.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs new file mode 100644 index 0000000000000000000000000000000000000000..5845b1007de4267f86043862fe47cb1b59a963fd --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/TrackablesImpl.cs @@ -0,0 +1,163 @@ +// +// 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; + + /// + /// + /// + public TrackablesApiControllerImpl(TrackableService trackableService) + { + _trackableService = trackableService; + } + + + /// + /// 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); + if (mytrackable == null) + { + return StatusCode(409, "UUID already existing!"); + } + else 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) + { + // Access other service(s) + WorldLinkService _worldLinkService = WorldLinkService.Singleton as WorldLinkService; + + 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 = TypeWorldStorage.UNKNOWNEnum; + _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 = TypeWorldStorage.UNKNOWNEnum; + _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 0000000000000000000000000000000000000000..8d5e48bc1d4b4c1de5cb1c04f80f34d6dcc39ce6 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldAnchorsImpl.cs @@ -0,0 +1,165 @@ +// +// 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; + + /// + /// + /// + public WorldAnchorsApiControllerImpl(WorldAnchorService worldAnchorService) + { + _worldAnchorService = worldAnchorService; + } + + + /// + /// 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); + if (myworldanchor == null) + { + return StatusCode(409, "UUID alread exexisting!"); + } + else 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) + { + // Access other service(s) + WorldLinkService _worldLinkService = WorldLinkService.Singleton as WorldLinkService; + + 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 = TypeWorldStorage.UNKNOWNEnum; + _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 = TypeWorldStorage.UNKNOWNEnum; + _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 0000000000000000000000000000000000000000..cd5da8ac57a90b905ce163c9ef5423f5920f9db4 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ControllersImpl/WorldLinksImpl.cs @@ -0,0 +1,215 @@ +// +// 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 WorldLinkService _worldLinkService; + + /// + /// + /// + public WorldLinksApiControllerImpl(WorldLinkService worldLinkService) + { + _worldLinkService = worldLinkService; + } + + /// + /// 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); + if (myworldlink == null) + { + return StatusCode(409, "UUID already existing!"); + } + else 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) + { + // Access other service(s) + TrackableService _trackableService = TrackableService.Singleton as TrackableService; + WorldAnchorService _worldAnchorService = WorldAnchorService.Singleton as WorldAnchorService; + + WorldLink myworldlink = _worldLinkService.Get(worldLinkUUID); + if (null != myworldlink) + { + // check TypeFrom + if (myworldlink.TypeFrom == TypeWorldStorage.TRACKABLEEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + else if (myworldlink.TypeFrom == TypeWorldStorage.ANCHOREnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + // check TypeTo + if (myworldlink.TypeTo == TypeWorldStorage.TRACKABLEEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + else if (myworldlink.TypeTo == TypeWorldStorage.ANCHOREnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; + 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) + { + // 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) + { + // check TypeFrom + if (myworldlink.TypeFrom == TypeWorldStorage.TRACKABLEEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + else if (myworldlink.TypeFrom == TypeWorldStorage.ANCHOREnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDFrom)) + { + myworldlink.TypeFrom = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDFrom = Guid.Empty; + } + } + // check TypeTo + if (myworldlink.TypeTo == TypeWorldStorage.TRACKABLEEnum) + { + if (null == _trackableService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; + myworldlink.UUIDTo = Guid.Empty; + } + } + else if (myworldlink.TypeTo == TypeWorldStorage.ANCHOREnum) + { + if (null == _worldAnchorService.Get(myworldlink.UUIDTo)) + { + myworldlink.TypeTo = TypeWorldStorage.UNKNOWNEnum; + 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/ModelsExt/IModels.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/IModels.cs new file mode 100644 index 0000000000000000000000000000000000000000..0c033f84a8072d9392e11d71fe8225aede3bab68 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/ETSI-ARF/ModelsExt/IModels.cs @@ -0,0 +1,38 @@ +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; } + + /// + /// UUID is managed by ARF + /// + 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 0000000000000000000000000000000000000000..a6561a19e9b49db031ce02134a178dc1d0361ddc --- /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 0000000000000000000000000000000000000000..d534fb72ab3cae4e3a71055e85b12e01e3260822 --- /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 0000000000000000000000000000000000000000..6ae00227942c16651e547456da25d616e124c288 --- /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 new file mode 100644 index 0000000000000000000000000000000000000000..90e909ed8457dbb58ecf172d8fb421e2bc531a97 --- /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) + { + 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; + + // 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 UUID document already exists! + public bool CheckIfExist(Guid UUID) + { + foreach (var obj in Get()) + { + if (((Models.IModels)obj).UUID == UUID) 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).UUID); + } + + 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 UUID doesn't exist + bool exist = CheckIfExist(((Models.IModels)obj).UUID); + 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 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 getMongoIDFromUUID(Guid UUID) + { + ObjectId _currentMongoID = ObjectId.Empty; + var i = mongoCollection.Find(_ => true); + //i.ForEachAsync(_compareAndRemember).Wait(); + i.ForEachAsync(doc => + { + if (_currentMongoID != ObjectId.Empty) return; // take the first one + if (((Models.IModels)doc).UUID == UUID) + { + _currentMongoID = ((Models.IModels)doc)._mongoID; + } + } + ).Wait(); + return _currentMongoID; + } + #endregion + + public long Replace(T obj) //=> assetCollection.ReplaceOne(asset => asset.UUID == UUID, obj); + { + // Which mongo document? + ObjectId mongoID = getMongoIDFromUUID(((Models.IModels)obj).UUID); + + // 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).UUID); + + public long Remove(Guid UUID) + { + //return mongoCollection.DeleteOne(o => ((Models.IModels)o).UUID == UUID); + + // Which mongo document? + ObjectId mongoID = getMongoIDFromUUID(UUID); + + // 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 UUID + public T Get(string name) => mongoCollection.Find(obj => ((Models.IModels)obj).Name == name).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 UUID) + { + foreach (T obj in Get()) + { + if (((Models.IModels)obj).UUID == UUID) 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 0000000000000000000000000000000000000000..6327b3d204cad58a007fef2f0e888536223b3c13 --- /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 CollectionNameTrackables { get; set; } + public string CollectionNameWorldAnchors { get; set; } + public string CollectionNameWorldLinks { 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 CollectionNameTrackables { 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 93f177d61574831e98d067472c7bf25a98e79e4d..c7601cb22b3d1ede3738f9d8e7cecee6207b1756 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 0000000000000000000000000000000000000000..2b50133bc231dd05ecf22c682875bae819f19898 --- /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 0000000000000000000000000000000000000000..dac8abd63734ed230b56cd24ad2915ba603c9b17 --- /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/Program.cs b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..a99fc849c853d1c2efb1e3a0af4c9a7fc995776f --- /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 0000000000000000000000000000000000000000..2978f0ad5a5b4b25c7cbc8693f1673badfdf250c --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/Startup.cs @@ -0,0 +1,203 @@ +/* + * 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.1.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 + IServiceCollection c = 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(); + 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) + { + // + // Initialize all ARF services + // + app.ApplicationServices.GetRequiredService(); + app.ApplicationServices.GetRequiredService(); + app.ApplicationServices.GetRequiredService(); + + 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.Development.json b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.Development.json new file mode 100644 index 0000000000000000000000000000000000000000..e203e9407e74a6b9662aab8fde5d73ae64665f18 --- /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 0000000000000000000000000000000000000000..f7404687ec93f6d3dc634d7051b291f4b9e30458 --- /dev/null +++ b/server/worldstorage/src/ETSI.ARF.OpenAPI.WorldStorage/appsettings.json @@ -0,0 +1,18 @@ +{ + "DatabaseSettings": { + "Description" : "Version for Visual Studio", + "LocalDataPath": ".\\wwwroot\\dataspace\\data", + "MongoSrv": "192-168-020-029.fe.hhi.de", + "MongoPort": "27037", + "DatabaseName": "WorldStorageAPI", + "CollectionNameWorldLinks": "WorldLinks", + "CollectionNameTrackables": "Trackables", + "CollectionNameWorldAnchors": "WorldAnchors" + }, + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +}