diff --git a/src/IO.Swagger.Lib.V3.Tests/Controllers/SubmodelRepositoryAPIApiControllerTests.cs b/src/IO.Swagger.Lib.V3.Tests/Controllers/SubmodelRepositoryAPIApiControllerTests.cs index af5351338..62a4fa0c8 100644 --- a/src/IO.Swagger.Lib.V3.Tests/Controllers/SubmodelRepositoryAPIApiControllerTests.cs +++ b/src/IO.Swagger.Lib.V3.Tests/Controllers/SubmodelRepositoryAPIApiControllerTests.cs @@ -15,8 +15,10 @@ namespace AasxServerBlazorTests.Controllers; +using System.Reflection.Emit; using System.Security.Claims; using System.Security.Principal; +using System.Xml.Linq; using AasCore.Aas3_0; using AasxServer; using AasxServerStandardBib.Interfaces; @@ -282,9 +284,10 @@ public void GetAllSubmodelElements_WithValidRequest_ReturnsPagedResult(string su _authorizationServiceMock.Setup(x => x.AuthorizeAsync(It.IsAny(), It.IsAny(), "SecurityPolicy")) .Returns(Task.FromResult(AuthorizationResult.Success())); - + var levelString = nameof(level); + var extentString = nameof(extent); // Act - var result = _controller.GetAllSubmodelElements(submodelIdentifier, limit, cursor, level, extent, diff); + var result = _controller.GetAllSubmodelElements(submodelIdentifier, limit, cursor, levelString, extentString, diff); // Assert result.Should().BeOfType(); @@ -303,8 +306,11 @@ public void GetAllSubmodelElements_WhenDecodingReturnedNull_ThrowsNotAllowedExce _decoderServiceMock.Setup(x => x.Decode("submodelIdentifier", submodelIdentifier)).Returns((string)null); + var levelString = nameof(LevelEnum.Deep); + var extentString = nameof(ExtentEnum.WithoutBlobValue); + // Act - Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, LevelEnum.Deep, ExtentEnum.WithoutBlobValue, null); + Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, levelString, extentString, null); // Assert action.Should().ThrowExactly().WithMessage($"Decoding {submodelIdentifier} returned null"); @@ -325,8 +331,11 @@ public void GetAllSubmodelElements_WhenAuthorizationFails_ThrowsNotAllowedExcept Program.noSecurity = false; + var levelString = nameof(LevelEnum.Core); + var extentString = nameof(ExtentEnum.WithBlobValue); + // Act - Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, LevelEnum.Core, ExtentEnum.WithBlobValue, null); + Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, levelString, extentString, null); // Assert action.Should().ThrowExactly(); @@ -352,8 +361,12 @@ public void GetAllSubmodelElements_WithValidRequestAndDiffParameter_FiltersSubmo //_paginationServiceMock.Setup(x => x.GetPaginatedList(It.IsAny>(), It.IsAny())) // .Returns((List elements, PaginationParameters parameters) => new List(elements)); + + var levelString = nameof(LevelEnum.Deep); + var extentString = nameof(ExtentEnum.WithoutBlobValue); + // Act - Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, LevelEnum.Deep, ExtentEnum.WithBlobValue, diffParameterValue); + Action action = () => _controller.GetAllSubmodelElements(submodelIdentifier, null, null, levelString, extentString, diffParameterValue); // Assert action.Should().NotThrow(); // Ensure no exception is thrown diff --git a/src/IO.Swagger.Lib.V3.Tests/Services/GenerateSerializationServiceTests.cs b/src/IO.Swagger.Lib.V3.Tests/Services/GenerateSerializationServiceTests.cs index f71836979..6ca963502 100644 --- a/src/IO.Swagger.Lib.V3.Tests/Services/GenerateSerializationServiceTests.cs +++ b/src/IO.Swagger.Lib.V3.Tests/Services/GenerateSerializationServiceTests.cs @@ -60,7 +60,7 @@ public void Constructor_ShouldThrowArgumentNullException_WhenSubmodelServiceIsNu public void GenerateSerializationByIds_ShouldReturnEmptyEnvironment_WhenNoIdsProvided() { // Arrange - _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([]); + _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([]); _mockSubmodelService.Setup(x => x.GetAllSubmodels()).Returns([]); // Act @@ -79,7 +79,7 @@ public void GenerateSerializationByIds_ShouldFetchAASs_WhenAasIdsProvided() var mockAas = new Mock(); mockAas.SetupGet(x => x.Id).Returns(aasId); - _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([mockAas.Object]); + _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([mockAas.Object]); _mockSubmodelService.Setup(x => x.GetAllSubmodels()).Returns([]); // Act @@ -98,7 +98,7 @@ public void GenerateSerializationByIds_ShouldFetchSubmodels_WhenSubmodelIdsProvi var mockSubmodel = new Mock(); mockSubmodel.SetupGet(x => x.Id).Returns(submodelId); - _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([]); + _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([]); _mockSubmodelService.Setup(x => x.GetAllSubmodels()).Returns([mockSubmodel.Object]); // Act @@ -122,7 +122,7 @@ public void GenerateSerializationByIds_ShouldFetchAASsAndSubmodels_WhenBothIdsPr var mockSubmodel = new Mock(); mockSubmodel.SetupGet(x => x.Id).Returns(submodelId); - _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([mockAas.Object]); + _mockAasService.Setup(x => x.GetAllAssetAdministrationShells(It.IsAny?>(), It.IsAny())).Returns([mockAas.Object]); _mockSubmodelService.Setup(x => x.GetAllSubmodels()).Returns([mockSubmodel.Object]); // Act diff --git a/src/IO.Swagger.Lib.V3/Controllers/SubmodelRepositoryAPIApi.cs b/src/IO.Swagger.Lib.V3/Controllers/SubmodelRepositoryAPIApi.cs index 30866964c..5f31f2538 100644 --- a/src/IO.Swagger.Lib.V3/Controllers/SubmodelRepositoryAPIApi.cs +++ b/src/IO.Swagger.Lib.V3/Controllers/SubmodelRepositoryAPIApi.cs @@ -1,22 +1,23 @@ -/******************************************************************************** -* Copyright (c) {2019 - 2024} Contributors to the Eclipse Foundation -* -* See the NOTICE file(s) distributed with this work for additional -* information regarding copyright ownership. -* -* This program and the accompanying materials are made available under the -* terms of the Apache License Version 2.0 which is available at -* https://www.apache.org/licenses/LICENSE-2.0 -* -* SPDX-License-Identifier: Apache-2.0 -********************************************************************************/ - +/******************************************************************************** +* Copyright (c) {2019 - 2024} Contributors to the Eclipse Foundation +* +* See the NOTICE file(s) distributed with this work for additional +* information regarding copyright ownership. +* +* This program and the accompanying materials are made available under the +* terms of the Apache License Version 2.0 which is available at +* https://www.apache.org/licenses/LICENSE-2.0 +* +* SPDX-License-Identifier: Apache-2.0 +********************************************************************************/ + +namespace IO.Swagger.Controllers; /* * DotAAS Part 2 | HTTP/REST | Submodel Repository Service Specification * * The entire Submodel Repository Service Specification as part of the [Specification of the Asset Administration Shell: Part 2](http://industrialdigitaltwin.org/en/content-hub). Publisher: Industrial Digital Twin Association (IDTA) 2023 * - * OpenAPI spec version: V3.0.1_SSP-001 + * OpenAPI spec version: V3.0.3_SSP-001 * Contact: info@idtwin.org * Generated by: https://github.com/swagger-api/swagger-codegen.git */ @@ -45,14 +46,10 @@ using System.Linq; using System.Net.Mime; using System.Security.Claims; - -namespace IO.Swagger.Controllers; - -using System.Globalization; using System.Threading.Tasks; using AdminShellNS.Exceptions; -using Microsoft.IdentityModel.Tokens; - +using Microsoft.IdentityModel.Tokens; + /// /// /// @@ -70,25 +67,27 @@ public class SubmodelRepositoryAPIApiController : ControllerBase private readonly ILevelExtentModifierService _levelExtentModifierService; private readonly IPaginationService _paginationService; private readonly IAuthorizationService _authorizationService; - private readonly IAdminShellPackageEnvironmentService _adminShellPackageEnvironmentService; + private readonly IAdminShellPackageEnvironmentService _adminShellPackageEnvironmentService; + private readonly IValidateSerializationModifierService _validateModifierService; public SubmodelRepositoryAPIApiController(IAppLogger logger, IBase64UrlDecoderService decoderService, ISubmodelService submodelService, IReferenceModifierService referenceModifierService, IJsonQueryDeserializer jsonQueryDeserializer, IMappingService mappingService, IPathModifierService pathModifierService, ILevelExtentModifierService levelExtentModifierService, IPaginationService paginationService, IAuthorizationService authorizationService, - IAdminShellPackageEnvironmentService adminShellPackageEnvironmentService) + IAdminShellPackageEnvironmentService adminShellPackageEnvironmentService, IValidateSerializationModifierService validateModifierService) { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _decoderService = decoderService ?? throw new ArgumentNullException(nameof(decoderService)); - _submodelService = submodelService ?? throw new ArgumentNullException(nameof(submodelService)); - _referenceModifierService = referenceModifierService ?? throw new ArgumentNullException(nameof(referenceModifierService)); - _jsonQueryDeserializer = jsonQueryDeserializer ?? throw new ArgumentNullException(nameof(jsonQueryDeserializer)); - _mappingService = mappingService ?? throw new ArgumentNullException(nameof(mappingService)); - _pathModifierService = pathModifierService ?? throw new ArgumentNullException(nameof(pathModifierService)); - _levelExtentModifierService = levelExtentModifierService ?? throw new ArgumentNullException(nameof(levelExtentModifierService)); - _paginationService = paginationService ?? throw new ArgumentNullException(nameof(paginationService)); - _authorizationService = authorizationService ?? throw new ArgumentNullException(nameof(authorizationService)); - _adminShellPackageEnvironmentService = adminShellPackageEnvironmentService ?? throw new ArgumentNullException(nameof(adminShellPackageEnvironmentService)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _decoderService = decoderService ?? throw new ArgumentNullException(nameof(decoderService)); + _submodelService = submodelService ?? throw new ArgumentNullException(nameof(submodelService)); + _referenceModifierService = referenceModifierService ?? throw new ArgumentNullException(nameof(referenceModifierService)); + _jsonQueryDeserializer = jsonQueryDeserializer ?? throw new ArgumentNullException(nameof(jsonQueryDeserializer)); + _mappingService = mappingService ?? throw new ArgumentNullException(nameof(mappingService)); + _pathModifierService = pathModifierService ?? throw new ArgumentNullException(nameof(pathModifierService)); + _levelExtentModifierService = levelExtentModifierService ?? throw new ArgumentNullException(nameof(levelExtentModifierService)); + _paginationService = paginationService ?? throw new ArgumentNullException(nameof(paginationService)); + _authorizationService = authorizationService ?? throw new ArgumentNullException(nameof(authorizationService)); + _adminShellPackageEnvironmentService = adminShellPackageEnvironmentService ?? throw new ArgumentNullException(nameof(adminShellPackageEnvironmentService)); + _validateModifierService = validateModifierService ?? throw new ArgumentNullException(nameof(authorizationService)); } /// @@ -154,7 +153,7 @@ public virtual IActionResult DeleteFileByPathSubmodelRepo([FromRoute] [Required] /// Internal Server Error /// Default error handling for unmentioned status codes [HttpDelete] - [Route("/submodels/{submodelIdentifier}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}")] [ValidateModelState] [SwaggerOperation("DeleteSubmodelById")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -163,13 +162,13 @@ public virtual IActionResult DeleteFileByPathSubmodelRepo([FromRoute] [Required] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult DeleteSubmodelById([FromRoute] [Required] string submodelIdentifier) - { - var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); - - if (decodedSubmodelIdentifier == null) - { - throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); + public virtual IActionResult DeleteSubmodelById([FromRoute][Required] string submodelIdentifier) + { + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); + + if (decodedSubmodelIdentifier == null) + { + throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); } _logger.LogInformation($"Received a request to delete a submodel with id {decodedSubmodelIdentifier}"); @@ -191,7 +190,7 @@ public virtual IActionResult DeleteSubmodelById([FromRoute] [Required] string su /// Internal Server Error /// Default error handling for unmentioned status codes [HttpDelete] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] [ValidateModelState] [SwaggerOperation("DeleteSubmodelElementByPathSubmodelRepo")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -200,33 +199,34 @@ public virtual IActionResult DeleteSubmodelById([FromRoute] [Required] string su [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult DeleteSubmodelElementByPathSubmodelRepo([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath) - { - var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); - - if (decodedSubmodelIdentifier == null) - { - throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); - } - - if (!Program.noSecurity) - { - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; - var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); - var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; - if (!authResult.Succeeded) - { - throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); - } - } - - _logger.LogInformation($"Received a request to delete a submodel element at {idShortPath} from submodel with id {decodedSubmodelIdentifier}"); - - _submodelService.DeleteSubmodelElementByPath(decodedSubmodelIdentifier, idShortPath); - + public virtual IActionResult DeleteSubmodelElementByPathSubmodelRepo([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath) + { + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); + + if (decodedSubmodelIdentifier == null) + { + throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); + } + + if (!Program.noSecurity) + { + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; + var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); + var principal = new System.Security.Principal.GenericPrincipal(identity, null); + var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; + if (!authResult.Succeeded) + { + throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); + } + } + + _logger.LogInformation($"Received a request to delete a submodel element at {idShortPath} from submodel with id {decodedSubmodelIdentifier}"); + // return StatusCode(500, default(Result)); + + _submodelService.DeleteSubmodelElementByPath(decodedSubmodelIdentifier, idShortPath); + return NoContent(); } @@ -238,7 +238,6 @@ public virtual IActionResult DeleteSubmodelElementByPathSubmodelRepo([FromRoute] /// A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue /// Determines the structural depth of the respective resource content /// Determines to which extent the resource is being serialized - /// Filters response, only elements changed after DateTime /// List of found submodel elements /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -247,7 +246,7 @@ public virtual IActionResult DeleteSubmodelElementByPathSubmodelRepo([FromRoute] /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelElements")] [SwaggerResponse(statusCode: 200, type: typeof(GetSubmodelElementsResult), description: "List of found submodel elements")] @@ -257,51 +256,53 @@ public virtual IActionResult DeleteSubmodelElementByPathSubmodelRepo([FromRoute] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelElements([FromRoute] [Required] string submodelIdentifier, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent, - [FromQuery] string? diff) - { + public virtual IActionResult GetAllSubmodelElements([FromRoute][Required] string submodelIdentifier, + [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] string level, + [FromQuery] string extent, [FromQuery] string? diff) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); - if (decodedSubmodelIdentifier == null) - { - throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); - } - - _logger.LogInformation($"Received a request to get all the submodel elements from submodel with id {decodedSubmodelIdentifier}"); - if (!Program.noSecurity) - { - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; - if (!authResult.Succeeded) - { - throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); - } - } - - var submodelElements = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); - - var filtered = new List(); - if (!diff.IsNullOrEmpty()) - { - try - { - var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); - filtered = filterSubmodelElements(submodelElements, _diff); - } - catch - { - // ignored - } - } - else - filtered = submodelElements; - - var smePaginatedList = _paginationService.GetPaginatedList(filtered, new PaginationParameters(cursor, limit)); - var smeLevelList = _levelExtentModifierService.ApplyLevelExtent(smePaginatedList.result, level, extent); - var output = new PagedResult {result = smeLevelList, paging_metadata = smePaginatedList.paging_metadata}; - return new ObjectResult(output); + if (decodedSubmodelIdentifier == null) + { + throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); + } + + _logger.LogInformation($"Received a request to get all the submodel elements from submodel with id {decodedSubmodelIdentifier}"); + if (!Program.noSecurity) + { + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; + if (!authResult.Succeeded) + { + throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); + } + } + + var submodelElements = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); + + var filtered = new List(); + if (!diff.IsNullOrEmpty()) + { + try + { + var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); + filtered = filterSubmodelElements(submodelElements, _diff); + } + catch + { + // ignored + } + } + else + filtered = submodelElements; + + var smePaginatedList = _paginationService.GetPaginatedList(filtered, new PaginationParameters(cursor, limit)); + var smeLevelList = _levelExtentModifierService.ApplyLevelExtent(smePaginatedList.result, levelEnum, extentEnum); + var output = new PagedResult {result = smeLevelList, paging_metadata = smePaginatedList.paging_metadata}; + return new ObjectResult(output); } List filterSubmodelElements(List submodelElements, DateTime diff) @@ -427,7 +428,7 @@ public virtual IActionResult GetAllSubmodelElementsMetadataSubmodelRepo([FromRou if (!diff.IsNullOrEmpty()) { try - { + { var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); filtered = filterSubmodelElements(smeList, _diff); } @@ -453,7 +454,7 @@ public virtual IActionResult GetAllSubmodelElementsMetadataSubmodelRepo([FromRou /// The maximum number of elements in the response array /// A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue /// Determines the structural depth of the respective resource content - /// Filters response, only elements changed after DateTime + /// Filters response, only elements changed after DateTime /// List of found submodel elements in the Path notation /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -462,7 +463,7 @@ public virtual IActionResult GetAllSubmodelElementsMetadataSubmodelRepo([FromRou /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/$path")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/$path")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelElementsPathSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(List>), description: "List of found submodel elements in the Path notation")] @@ -472,50 +473,50 @@ public virtual IActionResult GetAllSubmodelElementsMetadataSubmodelRepo([FromRou [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelElementsPathSubmodelRepo([FromRoute] [Required] string submodelIdentifier, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] string? level, - [FromQuery] string? diff) - { + public virtual IActionResult GetAllSubmodelElementsPathSubmodelRepo([FromRoute][Required]string submodelIdentifier, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string? level, + [FromQuery] string? diff) + { var decodedSubmodelIdentifier = _decoderService.Decode($"submodelIdentifier", submodelIdentifier); - if (decodedSubmodelIdentifier == null) - { - throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); - } - - _logger.LogDebug($"Received request to get all the submodel elements from the submodel with id {decodedSubmodelIdentifier}"); - if (!Program.noSecurity) - { - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; - if (!authResult.Succeeded) - { - throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); - } - } - - var submodelElementList = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); - - var filtered = new List(); - if (!diff.IsNullOrEmpty()) - { - try - { - var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); - filtered = filterSubmodelElements(submodelElementList, _diff); - } - catch - { - // ignored - } - } - else - filtered = submodelElementList; - - // TODO (jtikekar, 2023-09-04): pagination and modifier - // TODO (jtikekar, 2023-09-04): not complete implemented - var output = _pathModifierService.ToIdShortPath(filtered); - return new ObjectResult(output); + if (decodedSubmodelIdentifier == null) + { + throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); + } + + _logger.LogDebug($"Received request to get all the submodel elements from the submodel with id {decodedSubmodelIdentifier}"); + if (!Program.noSecurity) + { + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; + if (!authResult.Succeeded) + { + throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); + } + } + + var submodelElementList = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); + + var filtered = new List(); + if (!diff.IsNullOrEmpty()) + { + try + { + var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); + filtered = filterSubmodelElements(submodelElementList, _diff); + } + catch + { + // ignored + } + } + else + filtered = submodelElementList; + + // TODO (jtikekar, 2023-09-04): pagination and modifier + // TODO (jtikekar, 2023-09-04): not complete implemented + var output = _pathModifierService.ToIdShortPath(filtered); + return new ObjectResult(output); } /// @@ -533,7 +534,7 @@ public virtual IActionResult GetAllSubmodelElementsPathSubmodelRepo([FromRoute] /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/$reference")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/$reference")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelElementsReferenceSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(GetReferencesResult), description: "List of found submodel elements")] @@ -543,9 +544,9 @@ public virtual IActionResult GetAllSubmodelElementsPathSubmodelRepo([FromRoute] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelElementsReferenceSubmodelRepo([FromRoute] [Required] string submodelIdentifier, [FromQuery] int? limit, - [FromQuery] string? cursor, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetAllSubmodelElementsReferenceSubmodelRepo([FromRoute][Required]string submodelIdentifier, [FromQuery]int? limit, + [FromQuery]string? cursor, [FromQuery]string level) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); if (decodedSubmodelIdentifier == null) @@ -580,7 +581,7 @@ public virtual IActionResult GetAllSubmodelElementsReferenceSubmodelRepo([FromRo /// A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue /// Determines the structural depth of the respective resource content /// Determines to which extent the resource is being serialized - /// Filters response, only elements changed after DateTime + /// Filters response, only elements changed after DateTime /// List of found submodel elements /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -589,7 +590,7 @@ public virtual IActionResult GetAllSubmodelElementsReferenceSubmodelRepo([FromRo /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/$value")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelElementsValueOnlySubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(ValueOnlyPagedResult), description: "List of found submodel elements")] @@ -599,48 +600,51 @@ public virtual IActionResult GetAllSubmodelElementsReferenceSubmodelRepo([FromRo [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelElementsValueOnlySubmodelRepo([FromRoute] [Required] string submodelIdentifier, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent, [FromQuery] string? diff) - { + public virtual IActionResult GetAllSubmodelElementsValueOnlySubmodelRepo([FromRoute][Required]string submodelIdentifier, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string level, + [FromQuery]string extent, [FromQuery] string? diff) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); - if (decodedSubmodelIdentifier == null) - { - throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); - } - - _logger.LogInformation($"Received request to get value of all the submodel elements from the submodel with id {decodedSubmodelIdentifier}"); - if (!Program.noSecurity) - { - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; - if (!authResult.Succeeded) - { - throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); - } - } - - var submodelElements = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); - - var filtered = new List(); - if (!diff.IsNullOrEmpty()) - { - try - { - var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); - filtered = filterSubmodelElements(submodelElements, _diff); - } - catch - { - // ignored - } - } - else - filtered = submodelElements; + if (decodedSubmodelIdentifier == null) + { + throw new NotAllowed($"Decoding {submodelIdentifier} returned null"); + } + + _logger.LogInformation($"Received request to get value of all the submodel elements from the submodel with id {decodedSubmodelIdentifier}"); + if (!Program.noSecurity) + { + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; + if (!authResult.Succeeded) + { + throw new NotAllowed(authResult.Failure.FailureReasons.FirstOrDefault()?.Message ?? string.Empty); + } + } + + var submodelElements = _submodelService.GetAllSubmodelElements(decodedSubmodelIdentifier); + + var filtered = new List(); + if (!diff.IsNullOrEmpty()) + { + try + { + var _diff = TimeStamp.TimeStamp.StringToDateTime(diff); + filtered = filterSubmodelElements(submodelElements, _diff); + } + catch + { + // ignored + } + } + else + filtered = submodelElements; var smePagedList = _paginationService.GetPaginatedList(filtered, new PaginationParameters(cursor, limit)); - var smeLevelExtent = _levelExtentModifierService.ApplyLevelExtent(smePagedList.result ?? [], level, extent); + var smeLevelExtent = _levelExtentModifierService.ApplyLevelExtent(smePagedList.result ?? [], levelEnum, extentEnum); var smeValues = _mappingService.Map(smeLevelExtent, "value"); var output = new ValueOnlyPagedResult() {result = smeValues.ConvertAll(sme => (IValueDTO)sme), paging_metadata = smePagedList.paging_metadata}; return new ObjectResult(output); @@ -662,7 +666,7 @@ public virtual IActionResult GetAllSubmodelElementsValueOnlySubmodelRepo([FromRo /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels")] + [Route("/api/v3.0/submodels")] [ValidateModelState] [SwaggerOperation("GetAllSubmodels")] [SwaggerResponse(statusCode: 200, type: typeof(PagedResult), description: "Requested Submodels")] @@ -671,10 +675,13 @@ public virtual IActionResult GetAllSubmodelElementsValueOnlySubmodelRepo([FromRo [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodels([FromQuery] [StringLength(3072, MinimumLength = 1)] string? semanticId, [FromQuery] string? idShort, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetAllSubmodels([FromQuery][StringLength(3072, MinimumLength=1)] string? semanticId, [FromQuery]string? idShort, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string level, + [FromQuery]string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); _logger.LogInformation($"Received a request to get all the submodels."); var reqSemanticId = _jsonQueryDeserializer.DeserializeReference("semanticId", semanticId); @@ -692,10 +699,10 @@ public virtual IActionResult GetAllSubmodels([FromQuery] [StringLength(3072, Min } var submodelsPagedList = _paginationService.GetPaginatedList(submodelList, new PaginationParameters(cursor, limit)); - var smLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelsPagedList.result, level, extent); + var smLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelsPagedList.result, levelEnum, extentEnum); var output = new PagedResult {result = smLevelList, paging_metadata = submodelsPagedList.paging_metadata}; return new ObjectResult(output); - } +} /// /// Returns the metadata attributes of all Submodels @@ -704,7 +711,7 @@ public virtual IActionResult GetAllSubmodels([FromQuery] [StringLength(3072, Min /// The Asset Administration Shell’s IdShort /// The maximum number of elements in the response array /// A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue - /// Determines the structural depth of the respective resource content + /// Determines the structural depth of the respective resource content /// Requested Submodels /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -712,7 +719,7 @@ public virtual IActionResult GetAllSubmodels([FromQuery] [StringLength(3072, Min /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/$metadata")] + [Route("/api/v3.0/submodels/$metadata")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelsMetadata")] [SwaggerResponse(statusCode: 200, type: typeof(MetadataPagedResult), description: "Requested Submodels")] @@ -721,8 +728,8 @@ public virtual IActionResult GetAllSubmodels([FromQuery] [StringLength(3072, Min [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelsMetadata([FromQuery] [StringLength(3072, MinimumLength = 1)] string? semanticId, [FromQuery] string? idShort, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level) + public virtual IActionResult GetAllSubmodelsMetadata([FromQuery][StringLength(3072, MinimumLength=1)]string? semanticId, [FromQuery]string? idShort, + [FromQuery]int? limit, [FromQuery]string? cursor) { _logger.LogInformation($"Received request to get the metadata of all the submodels."); @@ -741,8 +748,7 @@ public virtual IActionResult GetAllSubmodelsMetadata([FromQuery] [StringLength(3 } var submodelPagedList = _paginationService.GetPaginatedList(submodelList, new PaginationParameters(cursor, limit)); - var submodelLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelPagedList.result ?? [], level); - var smMetadataList = _mappingService.Map(submodelLevelList, "metadata"); + var smMetadataList = _mappingService.Map(submodelPagedList.result, "metadata"); var output = new MetadataPagedResult() {result = smMetadataList.ConvertAll(sme => (IMetadataDTO)sme), paging_metadata = submodelPagedList.paging_metadata}; return new ObjectResult(output); } @@ -762,7 +768,7 @@ public virtual IActionResult GetAllSubmodelsMetadata([FromQuery] [StringLength(3 /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/$path")] + [Route("/api/v3.0/submodels/$path")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelsPath")] [SwaggerResponse(statusCode: 200, type: typeof(GetPathItemsResult), description: "Requested Submodels")] @@ -771,9 +777,11 @@ public virtual IActionResult GetAllSubmodelsMetadata([FromQuery] [StringLength(3 [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelsPath([FromQuery] [StringLength(3072, MinimumLength = 1)] string semanticId, [FromQuery] string? idShort, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetAllSubmodelsPath([FromQuery][StringLength(3072, MinimumLength=1)]string? semanticId, [FromQuery]string? idShort, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string level) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); _logger.LogInformation($"Received request to get the metadata of all the submodels."); var reqSemanticId = _jsonQueryDeserializer.DeserializeReference("semanticId", semanticId); @@ -791,7 +799,7 @@ public virtual IActionResult GetAllSubmodelsPath([FromQuery] [StringLength(3072, } var submodelPagedList = _paginationService.GetPaginatedList(submodelList, new PaginationParameters(cursor, limit)); - var submodelLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelPagedList.result, level); + var submodelLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelPagedList.result, levelEnum); // TODO (jtikekar, 2023-09-04): @Andreas, what if the first element is property, where path is not applicable var submodelsPath = _pathModifierService.ToIdShortPath(submodelLevelList.ConvertAll(sm => (ISubmodel)sm)); var output = new PathPagedResult() {result = submodelsPath, paging_metadata = submodelPagedList.paging_metadata}; @@ -813,7 +821,7 @@ public virtual IActionResult GetAllSubmodelsPath([FromQuery] [StringLength(3072, /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/$reference")] + [Route("/api/v3.0/submodels/$reference")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelsReference")] [SwaggerResponse(statusCode: 200, type: typeof(GetReferencesResult), description: "References of the requested Submodels")] @@ -822,11 +830,10 @@ public virtual IActionResult GetAllSubmodelsPath([FromQuery] [StringLength(3072, [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelsReference([FromQuery] [StringLength(3072, MinimumLength = 1)] string? semanticId, [FromQuery] string? idShort, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetAllSubmodelsReference([FromQuery][StringLength(3072, MinimumLength=1)]string? semanticId, [FromQuery]string? idShort, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string level) + { _logger.LogInformation($"Received a request to get all the submodels."); - var reqSemanticId = _jsonQueryDeserializer.DeserializeReference("semanticId", semanticId); var submodelList = new List(); @@ -864,7 +871,7 @@ public virtual IActionResult GetAllSubmodelsReference([FromQuery] [StringLength( /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/$value")] + [Route("/api/v3.0/submodels/$value")] [ValidateModelState] [SwaggerOperation("GetAllSubmodelsValueOnly")] [SwaggerResponse(statusCode: 200, type: typeof(ValueOnlyPagedResult), description: "Requested Submodels")] @@ -874,10 +881,13 @@ public virtual IActionResult GetAllSubmodelsReference([FromQuery] [StringLength( [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetAllSubmodelsValueOnly([FromQuery] [StringLength(3072, MinimumLength = 1)] string? semanticId, [FromQuery] string? idShort, - [FromQuery] int? limit, [FromQuery] string? cursor, [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetAllSubmodelsValueOnly([FromQuery][StringLength(3072, MinimumLength=1)]string? semanticId, [FromQuery]string? idShort, + [FromQuery]int? limit, [FromQuery]string? cursor, [FromQuery]string level, + [FromQuery]string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); _logger.LogInformation($"Received a request to get all the submodels."); var reqSemanticId = _jsonQueryDeserializer.DeserializeReference("semanticId", semanticId); @@ -895,7 +905,7 @@ public virtual IActionResult GetAllSubmodelsValueOnly([FromQuery] [StringLength( } var submodelsPagedList = _paginationService.GetPaginatedList(submodelList, new PaginationParameters(cursor, limit)); - var submodelLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelsPagedList.result, level, extent); + var submodelLevelList = _levelExtentModifierService.ApplyLevelExtent(submodelsPagedList.result, levelEnum, extentEnum); var submodelsValue = _mappingService.Map(submodelLevelList, "value"); var output = new ValueOnlyPagedResult {result = submodelsValue.ConvertAll(sme => (IValueDTO)sme), paging_metadata = submodelsPagedList.paging_metadata}; return new ObjectResult(output); @@ -915,7 +925,7 @@ public virtual IActionResult GetAllSubmodelsValueOnly([FromQuery] [StringLength( /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment")] [ValidateModelState] [SwaggerOperation("GetFileByPathSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(byte[]), description: "Requested file")] @@ -926,8 +936,8 @@ public virtual IActionResult GetAllSubmodelsValueOnly([FromQuery] [StringLength( [SwaggerResponse(statusCode: 405, type: typeof(Result), description: "Method not allowed - Download only valid for File submodel element")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual async Task GetFileByPathSubmodelRepo([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath) - { + public virtual async Task GetFileByPathSubmodelRepo([FromRoute][Required]string submodelIdentifier, [FromRoute][Required]string idShortPath) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received a request to get file at {idShortPath} from submodel with id {decodedSubmodelIdentifier}"); @@ -954,10 +964,10 @@ public virtual async Task GetFileByPathSubmodelRepo([FromRoute] [ //content-disposition so that the aasx file can be downloaded from the web browser. ContentDisposition contentDisposition = new() - { - FileName = fileName ?? throw new NullValueException(nameof(fileName)), - Inline = fileName.EndsWith(".pdf", StringComparison.InvariantCulture) - }; + { + FileName = fileName ?? throw new NullValueException(nameof(fileName)), + Inline = fileName.EndsWith(".pdf", StringComparison.InvariantCulture) + }; HttpContext.Response.Headers.Append("Content-Disposition", contentDisposition.ToString()); HttpContext.Response.ContentLength = fileSize; @@ -989,7 +999,7 @@ public virtual async Task GetFileByPathSubmodelRepo([FromRoute] [ /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-results/{handleId}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-results/{handleId}")] [ValidateModelState] [SwaggerOperation("GetOperationAsyncResult")] [SwaggerResponse(statusCode: 200, type: typeof(OperationResult), description: "Operation result object")] @@ -999,38 +1009,9 @@ public virtual async Task GetFileByPathSubmodelRepo([FromRoute] [ [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetOperationAsyncResult([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromRoute] [Required] string handleId) - { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(OperationResult)); - - //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(400, default(Result)); - - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(Result)); - - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(Result)); - - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(Result)); - - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(Result)); - - //TODO: Uncomment the next line to return response 0 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(0, default(Result)); - string exampleJson = null; - exampleJson = "\"\""; - - var example = exampleJson != null - ? System.Text.Json.JsonSerializer.Deserialize(exampleJson) - : default(OperationResult); //TODO: Change the data returned - return new ObjectResult(example); - } - + public virtual IActionResult GetOperationAsyncResult([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromRoute][Required] string handleId) => throw new NotImplementedException(); + /// /// Returns the Operation result of an asynchronously invoked Operation /// @@ -1045,7 +1026,7 @@ public virtual IActionResult GetOperationAsyncResult([FromRoute] [Required] stri /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-results/{handleId}/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-results/{handleId}/$value")] [ValidateModelState] [SwaggerOperation("GetOperationAsyncResultValueOnly")] [SwaggerResponse(statusCode: 200, type: typeof(IValueDTO), description: "Value of the operation result object")] @@ -1055,10 +1036,9 @@ public virtual IActionResult GetOperationAsyncResult([FromRoute] [Required] stri [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetOperationAsyncResultValueOnly([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromRoute] [Required] string handleId) => - new ObjectResult(null); - + public virtual IActionResult GetOperationAsyncResultValueOnly([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromRoute][Required] string handleId) => throw new NotImplementedException(); + /// /// Returns the status of an asynchronously invoked Operation /// @@ -1074,48 +1054,20 @@ public virtual IActionResult GetOperationAsyncResultValueOnly([FromRoute] [Requi /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-status/{handleId}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/operation-status/{handleId}")] [ValidateModelState] [SwaggerOperation("GetOperationAsyncStatus")] - [SwaggerResponse(statusCode: 200, type: typeof(BaseOperationResult), - description: "Operation result object containing information that the 'executionState' is still 'Running'")] + [SwaggerResponse(statusCode: 200, type: typeof(BaseOperationResult), description: "Operation result object containing information that the 'executionState' is still 'Running'")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] [SwaggerResponse(statusCode: 401, type: typeof(Result), description: "Unauthorized, e.g. the server refused the authorization attempt.")] [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetOperationAsyncStatus([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromRoute] [Required] string handleId) - { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(BaseOperationResult)); - - //TODO: Uncomment the next line to return response 302 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(302); - - //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(400, default(Result)); - - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(Result)); - - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(Result)); - - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(Result)); - - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(Result)); - - //TODO: Uncomment the next line to return response 0 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(0, default(Result)); - - return new ObjectResult(System.Text.Json.JsonSerializer.Deserialize(string.Empty)); - } - - //TODO:jtikekar @Andreas the route is same as GetSubmodelById + public virtual IActionResult GetOperationAsyncStatus([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromRoute][Required] string handleId) => throw new NotImplementedException(); + + //TODO:jtikekar @Andreas the route is same as GetSubmodelById /// /// Returns a specific Submodel /// @@ -1160,7 +1112,7 @@ public virtual IActionResult GetSubmodelPolicyHeader([FromRoute] [Required] stri return Ok(); } - //TODO:jtikekar @Andreas what about GetSubmodel from AAS-Repo? + /// /// Returns a specific Submodel /// @@ -1174,9 +1126,8 @@ public virtual IActionResult GetSubmodelPolicyHeader([FromRoute] [Required] stri /// Not Found /// Internal Server Error /// Default error handling for unmentioned status codes - // [HttpHead] [HttpGet] - [Route("/submodels/{submodelIdentifier}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}")] [ValidateModelState] [SwaggerOperation("GetSubmodelById")] [SwaggerResponse(statusCode: 200, type: typeof(Submodel), description: "Requested Submodel")] @@ -1186,8 +1137,12 @@ public virtual IActionResult GetSubmodelPolicyHeader([FromRoute] [Required] stri [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submodelIdentifier, [FromQuery] LevelEnum level, [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetSubmodelById([FromRoute][Required] string submodelIdentifier, [FromQuery] string level, [FromQuery] string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the submodel with id {decodedSubmodelIdentifier}"); @@ -1196,7 +1151,7 @@ public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submo throw new NotAllowed($"Cannot proceed as {nameof(decodedSubmodelIdentifier)} is null"); } - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); var authResult = _authorizationService.AuthorizeAsync(User, submodel, "SecurityPolicy").Result; if (!authResult.Succeeded) { @@ -1209,7 +1164,7 @@ public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submo throw new NotAllowed("Policy incorrect!"); } - var output = _levelExtentModifierService.ApplyLevelExtent(submodel, level, extent); + var output = _levelExtentModifierService.ApplyLevelExtent(submodel, levelEnum, extentEnum); //TODO:jtikekar @Andreas, in earlier API policy set as getPolicy //Response.Headers.Add("policy", policy); @@ -1220,7 +1175,6 @@ public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submo /// Returns the metadata attributes of a specific Submodel /// /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) - /// Determines the structural depth of the respective resource content /// Requested Submodel in the metadata representation /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1229,7 +1183,7 @@ public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submo /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/$metadata")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$metadata")] [ValidateModelState] [SwaggerOperation("GetSubmodelByIdMetadata")] [SwaggerResponse(statusCode: 200, type: typeof(SubmodelMetadata), description: "Requested Submodel in the metadata representation")] @@ -1239,8 +1193,8 @@ public virtual IActionResult GetSubmodelById([FromRoute] [Required] string submo [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelByIdMetadata([FromRoute] [Required] string submodelIdentifier, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetSubmodelByIdMetadata([FromRoute][Required] string submodelIdentifier) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the metadata of the submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1259,8 +1213,7 @@ public virtual IActionResult GetSubmodelByIdMetadata([FromRoute] [Required] stri } } - var submodelLevel = _levelExtentModifierService.ApplyLevelExtent(submodel, level); - var output = _mappingService.Map(submodelLevel, "metadata"); + var output = _mappingService.Map(submodel, "metadata"); return new ObjectResult(output); } @@ -1277,7 +1230,7 @@ public virtual IActionResult GetSubmodelByIdMetadata([FromRoute] [Required] stri /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/$path")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$path")] [ValidateModelState] [SwaggerOperation("GetSubmodelByIdPath")] [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested Submodel")] @@ -1287,8 +1240,11 @@ public virtual IActionResult GetSubmodelByIdMetadata([FromRoute] [Required] stri [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelByIdPath([FromRoute] [Required] string submodelIdentifier, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetSubmodelByIdPath([FromRoute][Required] string submodelIdentifier, [FromQuery] string level) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the idShortPath of the submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1307,8 +1263,8 @@ public virtual IActionResult GetSubmodelByIdPath([FromRoute] [Required] string s } } - var submodelLevel = _levelExtentModifierService.ApplyLevelExtent(submodel, level); - var output = _pathModifierService.ToIdShortPath(submodelLevel); + var submodelLevel = _levelExtentModifierService.ApplyLevelExtent(submodel, levelEnum); + var output = _pathModifierService.ToIdShortPath(submodelLevel); return new ObjectResult(output); } @@ -1324,7 +1280,7 @@ public virtual IActionResult GetSubmodelByIdPath([FromRoute] [Required] string s /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/$reference")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$reference")] [ValidateModelState] [SwaggerOperation("GetSubmodelByIdReference")] [SwaggerResponse(statusCode: 200, type: typeof(Reference), description: "Requested Submodel")] @@ -1334,8 +1290,8 @@ public virtual IActionResult GetSubmodelByIdPath([FromRoute] [Required] string s [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelByIdReference([FromRoute] [Required] string submodelIdentifier) - { + public virtual IActionResult GetSubmodelByIdReference([FromRoute][Required] string submodelIdentifier) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the submodel with id {decodedSubmodelIdentifier}"); @@ -1373,7 +1329,7 @@ public virtual IActionResult GetSubmodelByIdReference([FromRoute] [Required] str /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$value")] [ValidateModelState] [SwaggerOperation("GetSubmodelByIdValueOnly")] [SwaggerResponse(statusCode: 200, type: typeof(SubmodelValue), description: "Requested Submodel")] @@ -1383,9 +1339,12 @@ public virtual IActionResult GetSubmodelByIdReference([FromRoute] [Required] str [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute] [Required] string submodelIdentifier, [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute][Required] string submodelIdentifier, [FromQuery] string level, [FromQuery] string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get value of submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1404,8 +1363,8 @@ public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute] [Required] str } } - var submodelLevel = _levelExtentModifierService.ApplyLevelExtent(submodel, level, extent); - var output = _mappingService.Map(submodelLevel, "value"); + var submodelLevel = _levelExtentModifierService.ApplyLevelExtent(submodel, levelEnum, extentEnum); + var output = _mappingService.Map(submodelLevel, "value"); return new ObjectResult(output); } @@ -1414,7 +1373,6 @@ public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute] [Required] str /// /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Determines the structural depth of the respective resource content /// Metadata attributes of the requested submodel element /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1423,7 +1381,7 @@ public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute] [Required] str /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$metadata")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$metadata")] [ValidateModelState] [SwaggerOperation("GetSubmodelElementByPathMetadataSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(ISubmodelElementMetadata), description: "Metadata attributes of the requested submodel element")] @@ -1433,9 +1391,8 @@ public virtual IActionResult GetSubmodelByIdValueOnly([FromRoute] [Required] str [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get metadata of submodel element at {idShortPath} from the submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1448,9 +1405,9 @@ public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromR { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; - var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; + var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); + var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; if (!authResult.Succeeded) { @@ -1458,8 +1415,7 @@ public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromR } } - var smeLevel = _levelExtentModifierService.ApplyLevelExtent(submodelElement, level); - var output = _mappingService.Map(smeLevel, "metadata"); + var output = _mappingService.Map(submodelElement, "metadata"); return new ObjectResult(output); } @@ -1470,7 +1426,7 @@ public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromR /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) /// Determines the structural depth of the respective resource content - /// Requested submodel element + /// Submodel elements in path notation /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. /// Forbidden @@ -1478,19 +1434,21 @@ public virtual IActionResult GetSubmodelElementByPathMetadataSubmodelRepo([FromR /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$path")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$path")] [ValidateModelState] [SwaggerOperation("GetSubmodelElementByPathPathSubmodelRepo")] - [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Requested submodel element")] + [SwaggerResponse(statusCode: 200, type: typeof(List), description: "Submodel elements in path notation")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] [SwaggerResponse(statusCode: 401, type: typeof(Result), description: "Unauthorized, e.g. the server refused the authorization attempt.")] [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level) - { + public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, [FromQuery] string level) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to path of the submodel element at {idShortPath} from a submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1503,9 +1461,9 @@ public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; - var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; + var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); + var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; if (!authResult.Succeeded) { @@ -1513,8 +1471,8 @@ public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute } } - var submodelElementLevel = _levelExtentModifierService.ApplyLevelExtent(submodelElement, level); - var output = _pathModifierService.ToIdShortPath(submodelElementLevel); + var submodelElementLevel = _levelExtentModifierService.ApplyLevelExtent(submodelElement, levelEnum); + var output = _pathModifierService.ToIdShortPath(submodelElementLevel); return new ObjectResult(output); } @@ -1523,7 +1481,6 @@ public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute /// /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Determines the structural depth of the respective resource content /// Requested submodel element /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1532,7 +1489,7 @@ public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$reference")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$reference")] [ValidateModelState] [SwaggerOperation("GetSubmodelElementByPathReferenceSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(Reference), description: "Requested submodel element")] @@ -1542,9 +1499,9 @@ public virtual IActionResult GetSubmodelElementByPathPathSubmodelRepo([FromRoute [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelElementByPathReferenceSubmodelRepo([FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, [FromQuery] LevelEnum level) - { + public virtual IActionResult GetSubmodelElementByPathReferenceSubmodelRepo([FromRoute][Required] string submodelIdentifier, + [FromRoute][Required] string idShortPath) + { var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get reference of the submodel element atv{idShortPath} from the submodel with id {decodedSubmodelIdentifier}"); @@ -1558,7 +1515,7 @@ public virtual IActionResult GetSubmodelElementByPathReferenceSubmodelRepo([From { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; + var claimsList = new List(User.Claims) {new("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; @@ -1589,7 +1546,7 @@ public virtual IActionResult GetSubmodelElementByPathReferenceSubmodelRepo([From /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] [ValidateModelState] [SwaggerOperation("GetSubmodelElementByPathSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(ISubmodelElement), description: "Requested submodel element")] @@ -1599,9 +1556,13 @@ public virtual IActionResult GetSubmodelElementByPathReferenceSubmodelRepo([From [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level, [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromQuery] string level, [FromQuery] string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the submodel element at {idShortPath} from the submodel with id {decodedSubmodelIdentifier}"); @@ -1615,7 +1576,7 @@ public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute] [R { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; @@ -1627,7 +1588,7 @@ public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute] [R var submodelElement = _submodelService.GetSubmodelElementByPath(decodedSubmodelIdentifier, idShortPath); - var output = _levelExtentModifierService.ApplyLevelExtent(submodelElement, level, extent); + var output = _levelExtentModifierService.ApplyLevelExtent(submodelElement, levelEnum, extentEnum); return new ObjectResult(output); } @@ -1646,7 +1607,7 @@ public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute] [R /// Internal Server Error /// Default error handling for unmentioned status codes [HttpGet] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value")] [ValidateModelState] [SwaggerOperation("GetSubmodelElementByPathValueOnlySubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(ISubmodelElementValue), description: "Requested submodel element")] @@ -1656,11 +1617,13 @@ public virtual IActionResult GetSubmodelElementByPathSubmodelRepo([FromRoute] [R [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level, - [FromQuery] ExtentEnum extent) - { + public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([FromRoute][Required] string submodelIdentifier, + [FromRoute][Required] string idShortPath, [FromQuery] string level, [FromQuery] string extent) + { + //Validate level and extent + var levelEnum = _validateModifierService.ValidateLevel(level); + var extentEnum = _validateModifierService.ValidateExtent(extent); + var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); _logger.LogInformation($"Received request to get the value of the submodel element at {idShortPath} from the submodel with id {decodedSubmodelIdentifier}"); if (decodedSubmodelIdentifier == null) @@ -1672,7 +1635,7 @@ public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([From { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; @@ -1684,8 +1647,8 @@ public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([From var submodelElement = _submodelService.GetSubmodelElementByPath(decodedSubmodelIdentifier, idShortPath); - var submodelElementLevel = _levelExtentModifierService.ApplyLevelExtent(submodelElement, level, extent); - var output = _mappingService.Map(submodelElementLevel, "value"); + var submodelElementLevel = _levelExtentModifierService.ApplyLevelExtent(submodelElement, levelEnum, extentEnum); + var output = _mappingService.Map(submodelElementLevel, "value"); return new ObjectResult(output); } @@ -1704,7 +1667,7 @@ public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([From /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke-async")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke-async")] [ValidateModelState] [SwaggerOperation("InvokeOperationAsync")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -1714,36 +1677,9 @@ public virtual IActionResult GetSubmodelElementByPathValueOnlySubmodelRepo([From [SwaggerResponse(statusCode: 405, type: typeof(Result), description: "Method not allowed - Invoke only valid for Operation submodel element")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult InvokeOperationAsync([FromBody] OperationRequest? body, [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath) - { - //TODO: Uncomment the next line to return response 202 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(202); - - //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(400, default(Result)); - - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(Result)); - - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(Result)); - - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(Result)); - - //TODO: Uncomment the next line to return response 405 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(405, default(Result)); - - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(Result)); - - //TODO: Uncomment the next line to return response 0 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(0, default(Result)); - - throw new NotImplementedException(); - } - + public virtual IActionResult InvokeOperationAsync([FromBody] OperationRequest? body, [FromRoute][Required] string submodelIdentifier, + [FromRoute][Required] string idShortPath) => throw new NotImplementedException(); + /// /// Asynchronously invokes an Operation at a specified path /// @@ -1759,7 +1695,7 @@ public virtual IActionResult InvokeOperationAsync([FromBody] OperationRequest? b /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke-async/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke-async/$value")] [ValidateModelState] [SwaggerOperation("InvokeOperationAsyncValueOnly")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -1768,40 +1704,16 @@ public virtual IActionResult InvokeOperationAsync([FromBody] OperationRequest? b [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult InvokeOperationAsyncValueOnly([FromBody] object? body, [FromRoute] [Required] string aasIdentifier, - [FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath) - { - //TODO: Uncomment the next line to return response 202 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(202); - - //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(400, default(Result)); - - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(Result)); - - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(Result)); - - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(Result)); - - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(Result)); - - //TODO: Uncomment the next line to return response 0 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(0, default(Result)); - - throw new NotImplementedException(); - } - + public virtual IActionResult InvokeOperationAsyncValueOnly([FromBody] OperationRequestValueOnly body, [FromRoute][Required] string aasIdentifier, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath) => throw new NotImplementedException(); + /// /// Synchronously or asynchronously invokes an Operation at a specified path /// /// Operation request object /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Determines whether an operation invocation is performed asynchronously or synchronously + /// Determines whether an operation invocation is performed asynchronously or synchronously /// Operation result object /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1811,7 +1723,7 @@ public virtual IActionResult InvokeOperationAsyncValueOnly([FromBody] object? bo /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke")] [ValidateModelState] [SwaggerOperation("InvokeOperationSubmodelRepo")] [SwaggerResponse(statusCode: 200, type: typeof(OperationResult), description: "Operation result object")] @@ -1822,35 +1734,9 @@ public virtual IActionResult InvokeOperationAsyncValueOnly([FromBody] object? bo [SwaggerResponse(statusCode: 405, type: typeof(Result), description: "Method not allowed - Invoke only valid for Operation submodel element")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult InvokeOperationSubmodelRepo([FromBody] OperationRequest? body, [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, [FromQuery] bool async) - { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(200, default(OperationResult)); - - //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(400, default(Result)); - - //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(401, default(Result)); - - //TODO: Uncomment the next line to return response 403 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(403, default(Result)); - - //TODO: Uncomment the next line to return response 404 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(404, default(Result)); - - //TODO: Uncomment the next line to return response 405 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(405, default(Result)); - - //TODO: Uncomment the next line to return response 500 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(500, default(Result)); - - //TODO: Uncomment the next line to return response 0 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - // return StatusCode(0, default(Result)); - return new ObjectResult(System.Text.Json.JsonSerializer.Deserialize(string.Empty)); - } - + public virtual IActionResult InvokeOperationSubmodelRepo([FromBody] OperationRequest body, [FromRoute][Required] string submodelIdentifier, + [FromRoute][Required] string idShortPath, [FromQuery] bool? _async) => throw new NotImplementedException(); + /// /// Synchronously or asynchronously invokes an Operation at a specified path /// @@ -1858,7 +1744,7 @@ public virtual IActionResult InvokeOperationSubmodelRepo([FromBody] OperationReq /// The Asset Administration Shell’s unique id (UTF8-BASE64-URL-encoded) /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Determines whether an operation invocation is performed asynchronously or synchronously + /// Determines whether an operation invocation is performed asynchronously or synchronously /// Operation result object /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1867,7 +1753,7 @@ public virtual IActionResult InvokeOperationSubmodelRepo([FromBody] OperationReq /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/invoke/$value")] [ValidateModelState] [SwaggerOperation("InvokeOperationValueOnly")] [SwaggerResponse(statusCode: 200, type: typeof(IValueDTO), description: "Operation result object")] @@ -1877,11 +1763,10 @@ public virtual IActionResult InvokeOperationSubmodelRepo([FromBody] OperationReq [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult InvokeOperationValueOnly([FromBody] object? body, [FromRoute] [Required] string aasIdentifier, - [FromRoute] [Required] string submodelIdentifier, [FromRoute] [Required] string idShortPath, - [FromQuery] bool async) => - new ObjectResult(null); - + public virtual IActionResult InvokeOperationValueOnly([FromBody] OperationRequestValueOnly body, [FromRoute][Required] string aasIdentifier, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromQuery] bool? _async) => throw new NotImplementedException(); + /// /// Updates an existing Submodel /// @@ -1896,7 +1781,7 @@ public virtual IActionResult InvokeOperationValueOnly([FromBody] object? body, [ /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}")] [ValidateModelState] [SwaggerOperation("PatchSubmodelById")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -1905,8 +1790,8 @@ public virtual IActionResult InvokeOperationValueOnly([FromBody] object? body, [ [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelById([FromBody] Submodel? body, [FromRoute] [Required] string submodelIdentifier, [FromQuery] LevelEnum level) - { + public virtual IActionResult PatchSubmodelById([FromBody]Submodel? body, [FromRoute][Required] string submodelIdentifier, [FromQuery] string level) + { if (body == null) { throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); @@ -1930,7 +1815,6 @@ public virtual IActionResult PatchSubmodelById([FromBody] Submodel? body, [FromR /// /// The metadata attributes of the Submodel object /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) - /// Determines the structural depth of the respective resource content /// Submodel updated successfully /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -1939,7 +1823,7 @@ public virtual IActionResult PatchSubmodelById([FromBody] Submodel? body, [FromR /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}/$metadata")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$metadata")] [ValidateModelState] [SwaggerOperation("PatchSubmodelByIdMetadata")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -1948,9 +1832,8 @@ public virtual IActionResult PatchSubmodelById([FromBody] Submodel? body, [FromR [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelByIdMetadata([FromBody] SubmodelMetadata? body, [FromRoute] [Required] string? submodelIdentifier, - [FromQuery] LevelEnum level) - { + public virtual IActionResult PatchSubmodelByIdMetadata([FromBody]SubmodelMetadata? body, [FromRoute][Required] string? submodelIdentifier) + { if (body == null) { throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); @@ -1989,7 +1872,7 @@ public virtual IActionResult PatchSubmodelByIdMetadata([FromBody] SubmodelMetada /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/$value")] [ValidateModelState] [SwaggerOperation("PatchSubmodelByIdValueOnly")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -1998,12 +1881,12 @@ public virtual IActionResult PatchSubmodelByIdMetadata([FromBody] SubmodelMetada [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelByIdValueOnly([FromBody] SubmodelValue? body, [FromRoute] [Required] string submodelIdentifier, - [FromQuery] LevelEnum level) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PatchSubmodelByIdValueOnly([FromBody]SubmodelValue? body, [FromRoute][Required]string submodelIdentifier, + [FromQuery]string level) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2031,7 +1914,6 @@ public virtual IActionResult PatchSubmodelByIdValueOnly([FromBody] SubmodelValue /// Metadata attributes of the SubmodelElement /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Determines the structural depth of the respective resource content /// SubmodelElement updated successfully /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -2040,7 +1922,7 @@ public virtual IActionResult PatchSubmodelByIdValueOnly([FromBody] SubmodelValue /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$metadata")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$metadata")] [ValidateModelState] [SwaggerOperation("PatchSubmodelElementByPathMetadataSubmodelRepo")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -2049,14 +1931,12 @@ public virtual IActionResult PatchSubmodelByIdValueOnly([FromBody] SubmodelValue [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelElementByPathMetadataSubmodelRepo([FromBody] ISubmodelElementMetadata? body, - [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PatchSubmodelElementByPathMetadataSubmodelRepo([FromBody] ISubmodelElementMetadata? body, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2094,7 +1974,7 @@ public virtual IActionResult PatchSubmodelElementByPathMetadataSubmodelRepo([Fro /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] [ValidateModelState] [SwaggerOperation("PatchSubmodelElementByPathSubmodelRepo")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -2103,12 +1983,12 @@ public virtual IActionResult PatchSubmodelElementByPathMetadataSubmodelRepo([Fro [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, [FromQuery] LevelEnum level) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PatchSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, [FromRoute][Required] string submodelIdentifier, + [FromRoute][Required] string idShortPath, [FromQuery] string level) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2138,7 +2018,7 @@ public virtual IActionResult PatchSubmodelElementByPathSubmodelRepo([FromBody] I /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPatch] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value")] [ValidateModelState] [SwaggerOperation("PatchSubmodelElementByPathValueOnlySubmodelRepo")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -2147,14 +2027,13 @@ public virtual IActionResult PatchSubmodelElementByPathSubmodelRepo([FromBody] I [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PatchSubmodelElementByPathValueOnlySubmodelRepo([FromBody] ISubmodelElementValue? body, - [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PatchSubmodelElementByPathValueOnlySubmodelRepo([FromBody] ISubmodelElementValue? body, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromQuery] string level) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2179,7 +2058,7 @@ public virtual IActionResult PatchSubmodelElementByPathValueOnlySubmodelRepo([Fr /// Creates a new Submodel /// /// Submodel object - /// The AAS’s unique id (UTF8-BASE64-URL-encoded) + /// The AAS’s unique id (UTF8-BASE64-URL-encoded) /// Submodel created successfully /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -2188,23 +2067,21 @@ public virtual IActionResult PatchSubmodelElementByPathValueOnlySubmodelRepo([Fr /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels")] + [Route("/api/v3.0/submodels")] [ValidateModelState] [SwaggerOperation("PostSubmodel")] [SwaggerResponse(statusCode: 201, type: typeof(Submodel), description: "Submodel created successfully")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] [SwaggerResponse(statusCode: 401, type: typeof(Result), description: "Unauthorized, e.g. the server refused the authorization attempt.")] [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] - [SwaggerResponse(statusCode: 409, type: typeof(Result), - description: - "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] + [SwaggerResponse(statusCode: 409, type: typeof(Result), description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PostSubmodel([FromBody] Submodel body, [FromQuery] string aasIdentifier) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PostSubmodel([FromBody]Submodel body, [FromQuery] string aasIdentifier) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } _logger.LogInformation($"Received request to create a submodel."); @@ -2226,7 +2103,7 @@ public virtual IActionResult PostSubmodel([FromBody] Submodel body, [FromQuery] /// Requested submodel element /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) /// IdShort path to the submodel element (dot-separated) - /// Create element as first one in list + /// Create element as first one in list /// Submodel element created successfully /// Bad Request, e.g. the request parameters of the format of the request body is wrong. /// Unauthorized, e.g. the server refused the authorization attempt. @@ -2236,7 +2113,7 @@ public virtual IActionResult PostSubmodel([FromBody] Submodel body, [FromQuery] /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPost] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] [ValidateModelState] [SwaggerOperation("PostSubmodelElementByPathSubmodelRepo")] [SwaggerResponse(statusCode: 201, type: typeof(ISubmodelElement), description: "Submodel element created successfully")] @@ -2244,19 +2121,16 @@ public virtual IActionResult PostSubmodel([FromBody] Submodel body, [FromQuery] [SwaggerResponse(statusCode: 401, type: typeof(Result), description: "Unauthorized, e.g. the server refused the authorization attempt.")] [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] - [SwaggerResponse(statusCode: 409, type: typeof(Result), - description: - "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] + [SwaggerResponse(statusCode: 409, type: typeof(Result), description: "Conflict, a resource which shall be created exists already. Might be thrown if a Submodel or SubmodelElement with the same ShortId is contained in a POST request.")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PostSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, - [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, - bool first) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + public virtual IActionResult PostSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + bool first) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2270,7 +2144,7 @@ public virtual IActionResult PostSubmodelElementByPathSubmodelRepo([FromBody] IS { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); User.Claims.ToList().Add(new Claim("idShortPath", $"{submodel.IdShort}.{idShortPath}")); - var claimsList = new List(User.Claims) {new("IdShortPath", $"{submodel.IdShort}.{idShortPath}")}; + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{idShortPath}") }; var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; @@ -2314,7 +2188,7 @@ public virtual IActionResult PostSubmodelElementByPathSubmodelRepo([FromBody] IS [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] public virtual IActionResult PostSubmodelElementSubmodelRepo([FromBody] ISubmodelElement? body, - [FromRoute] [Required] string submodelIdentifier, + [FromRoute][Required] string submodelIdentifier, bool first) { if (body == null) @@ -2331,10 +2205,10 @@ public virtual IActionResult PostSubmodelElementSubmodelRepo([FromBody] ISubmode if (!Program.noSecurity) { - var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{body.IdShort}")}; - var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); + var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{body.IdShort}") }; + var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); + var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; if (!authResult.Succeeded) { @@ -2370,7 +2244,7 @@ public virtual IActionResult PostSubmodelElementSubmodelRepo([FromBody] ISubmode [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PutSubmodelById([FromBody] Submodel? body, [FromRoute] [Required] string submodelIdentifier) + public virtual IActionResult PutSubmodelById([FromBody] Submodel? body, [FromRoute][Required] string submodelIdentifier) { if (body == null) { @@ -2405,7 +2279,7 @@ public virtual IActionResult PutSubmodelById([FromBody] Submodel? body, [FromRou /// Internal Server Error /// Default error handling for unmentioned status codes [HttpPut] - [Route("/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] + [Route("/api/v3.0/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}")] [ValidateModelState] [SwaggerOperation("PutSubmodelElementByPathSubmodelRepo")] [SwaggerResponse(statusCode: 400, type: typeof(Result), description: "Bad Request, e.g. the request parameters of the format of the request body is wrong.")] @@ -2413,15 +2287,14 @@ public virtual IActionResult PutSubmodelById([FromBody] Submodel? body, [FromRou [SwaggerResponse(statusCode: 403, type: typeof(Result), description: "Forbidden")] [SwaggerResponse(statusCode: 404, type: typeof(Result), description: "Not Found")] [SwaggerResponse(statusCode: 500, type: typeof(Result), description: "Internal Server Error")] - [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] - public virtual IActionResult PutSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, - [FromRoute] [Required] string submodelIdentifier, - [FromRoute] [Required] string idShortPath, - [FromQuery] LevelEnum level) - { - if (body == null) - { - throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); + [SwaggerResponse(statusCode: 0, type: typeof(Result), description: "Default error handling for unmentioned status codes")] + public virtual IActionResult PutSubmodelElementByPathSubmodelRepo([FromBody] ISubmodelElement? body, + [FromRoute][Required] string submodelIdentifier, [FromRoute][Required] string idShortPath, + [FromQuery] string level) + { + if (body == null) + { + throw new NotAllowed($"Cannot proceed as {nameof(body)} is null"); } var decodedSubmodelIdentifier = _decoderService.Decode("submodelIdentifier", submodelIdentifier); @@ -2435,7 +2308,7 @@ public virtual IActionResult PutSubmodelElementByPathSubmodelRepo([FromBody] ISu if (!Program.noSecurity) { var submodel = _submodelService.GetSubmodelById(decodedSubmodelIdentifier); - var claimsList = new List(User.Claims) {new Claim("IdShortPath", $"{submodel.IdShort}.{body.IdShort}")}; + var claimsList = new List(User.Claims) { new("IdShortPath", $"{submodel.IdShort}.{body.IdShort}") }; var identity = new ClaimsIdentity(claimsList, "AasSecurityAuth"); var principal = new System.Security.Principal.GenericPrincipal(identity, null); var authResult = _authorizationService.AuthorizeAsync(principal, submodel, "SecurityPolicy").Result; @@ -2450,7 +2323,7 @@ public virtual IActionResult PutSubmodelElementByPathSubmodelRepo([FromBody] ISu return NoContent(); } - /// +/// /// Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy /// /// The Submodel’s unique id (UTF8-BASE64-URL-encoded) @@ -2499,4 +2372,4 @@ public virtual IActionResult PutFileByPathSubmodelRepo([FromRoute] [Required] st return NoContent(); } -} \ No newline at end of file +}