From c25336b5a471759913333a93644cbc51cee3333e Mon Sep 17 00:00:00 2001 From: "Beaugrand, Kevin" Date: Sun, 13 Feb 2022 10:29:05 +0100 Subject: [PATCH 1/3] Change paths and add API grouping in documentation --- .../Client/Pages/Configurations/ConfigDetail.razor | 2 +- .../Client/Pages/Configurations/Configs.razor | 2 +- .../Pages/DeviceModels/CreateDeviceModelPage.razor | 4 ++-- .../Pages/DeviceModels/DeleteDeviceModelPage.razor | 2 +- .../Pages/DeviceModels/DeviceModelDetailPage.razor | 10 +++++----- .../Pages/DeviceModels/DeviceModelListPage.razor | 2 +- .../Client/Pages/Devices/CreateDevicePage.razor | 2 +- .../Client/Pages/Devices/DeviceDetailPage.razor | 2 +- .../Pages/Edge_Devices/CreateEdgeDeviceDialog.razor | 2 +- .../EdgeDeviceDeleteConfirmationDialog.razor | 2 +- .../Pages/Edge_Devices/EdgeDeviceDetailPage.razor | 10 +++++----- .../Pages/Edge_Devices/EdgeDeviceListPage.razor | 2 +- .../LoRaWAN/Concentrator/ConcentratorDetailPage.razor | 4 ++-- .../LoRaWAN/Concentrator/ConcentratorListPage.razor | 2 +- .../LoRaWAN/Concentrator/CreateConcentratorPage.razor | 2 +- .../LoRaWAN/Concentrator/DeleteConcentratorPage.razor | 2 +- src/AzureIoTHub.Portal/Client/Program.cs | 2 +- .../Server/Controllers/ConcentratorsController.cs | 3 ++- .../Server/Controllers/ConfigsController.cs | 3 ++- ...Controller.cs => DeviceModelCommandsController.cs} | 11 ++++++----- .../Server/Controllers/DeviceModelsController.cs | 3 ++- .../Server/Controllers/DevicesController.cs | 3 ++- .../Server/Controllers/GatewaysController.cs | 3 ++- .../Server/Controllers/OIDCSettingsController.cs | 5 +++-- src/AzureIoTHub.Portal/Server/Startup.cs | 3 +++ 25 files changed, 49 insertions(+), 39 deletions(-) rename src/AzureIoTHub.Portal/Server/Controllers/{CommandsController.cs => DeviceModelCommandsController.cs} (88%) diff --git a/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor b/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor index bf01b3348..bc46d5bef 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor @@ -132,7 +132,7 @@ try { // Sends a GET request to the ConfigController, to retrieve a specific deployment from Azure IoT Hub - Config = await Http.GetFromJsonAsync($"api/Configs/{ConfigurationID}"); + Config = await Http.GetFromJsonAsync($"api/settings/oidc/{ConfigurationID}"); ConditionOwner = RetrieveCondition("owner"); ConditionEnv = RetrieveCondition("env"); ConditionType = RetrieveCondition("type"); diff --git a/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor b/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor index 5f50263e4..b90a1e9c9 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor @@ -93,7 +93,7 @@ { try { - result = await Http.GetFromJsonAsync("api/Configs"); + result = await Http.GetFromJsonAsync("api/settings/oidc"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/CreateDeviceModelPage.razor b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/CreateDeviceModelPage.razor index 657fce87b..e6a6edc15 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/CreateDeviceModelPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/CreateDeviceModelPage.razor @@ -156,11 +156,11 @@ private async Task Save() { - var result = await httpClient.PostAsJsonAsync("api/DeviceModels", DeviceModel); + var result = await httpClient.PostAsJsonAsync("api/models", DeviceModel); if (content is not null) { - var response = await httpClient.PostAsync($"api/DeviceModels/{DeviceModel.ModelId}/avatar", content); + var response = await httpClient.PostAsync($"api/models/{DeviceModel.ModelId}/avatar", content); } if (result.IsSuccessStatusCode) diff --git a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeleteDeviceModelPage.razor b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeleteDeviceModelPage.razor index b42fd42ea..69c981d51 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeleteDeviceModelPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeleteDeviceModelPage.razor @@ -30,7 +30,7 @@ private async Task DeleteDevice() { // var response = await Http.PostAsJsonAsync($"Devices/delete", device); - var response = await Http.DeleteAsync($"api/DeviceModels/{deviceModelID}"); + var response = await Http.DeleteAsync($"api/models/{deviceModelID}"); var errorMsg = await response.Content.ReadAsStringAsync(); // Prompts a snack bar to inform if the action was successful diff --git a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelDetailPage.razor index c2fadcc35..5b880b43d 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelDetailPage.razor @@ -127,13 +127,13 @@ protected override async Task OnInitializedAsync() { - DeviceModel = await httpClient.GetFromJsonAsync($"api/DeviceModels/{ModelID}"); - imageDataUrl = await httpClient.GetStringAsync($"api/DeviceModels/{ModelID}/avatar"); + DeviceModel = await httpClient.GetFromJsonAsync($"api/models/{ModelID}"); + imageDataUrl = await httpClient.GetStringAsync($"api/models/{ModelID}/avatar"); } async Task DeleteAvatar() { - await httpClient.DeleteAsync($"api/DeviceModels/{ModelID}/avatar"); + await httpClient.DeleteAsync($"api/models/{ModelID}/avatar"); imageDataUrl = null; } @@ -150,14 +150,14 @@ name: "\"file\"", fileName: e.File.Name); - var response = await httpClient.PostAsync($"api/DeviceModels/{ModelID}/avatar", content); + var response = await httpClient.PostAsync($"api/models/{ModelID}/avatar", content); imageDataUrl = await response.Content.ReadAsStringAsync(); } private async Task Save() { - var result = await httpClient.PutAsJsonAsync("api/DeviceModels", DeviceModel); + var result = await httpClient.PutAsJsonAsync("api/models", DeviceModel); if (result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelListPage.razor b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelListPage.razor index 2fbdf23fe..e95c30929 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelListPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/DeviceModels/DeviceModelListPage.razor @@ -101,7 +101,7 @@ { try { - result = await httpClient.GetFromJsonAsync("api/DeviceModels"); + result = await httpClient.GetFromJsonAsync("api/models"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Devices/CreateDevicePage.razor b/src/AzureIoTHub.Portal/Client/Pages/Devices/CreateDevicePage.razor index 21d6e0495..aca280f8b 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Devices/CreateDevicePage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Devices/CreateDevicePage.razor @@ -140,7 +140,7 @@ Device.IsEnabled = true; // Gets a list of device model previously registered to Azure to allow autocomplete field in the form - DeviceModelList = await Http.GetFromJsonAsync("api/DeviceModels"); + DeviceModelList = await Http.GetFromJsonAsync("api/models"); } /// diff --git a/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceDetailPage.razor index d6537d339..903b9cb7a 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceDetailPage.razor @@ -147,7 +147,7 @@ // Gets the DeviceModel Name from the DeviceModel ID if (!string.IsNullOrEmpty(Device.ModelId)) { - DeviceModel model = await Http.GetFromJsonAsync($"api/DeviceModels/{Device.ModelId}"); + DeviceModel model = await Http.GetFromJsonAsync($"api/models/{Device.ModelId}"); Device.ModelName = model?.Name; } diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor index 7d42a359a..fb5ac19fb 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor @@ -61,7 +61,7 @@ private async Task OnValidation() { - var result = await Http.PostAsJsonAsync("api/Gateways", gateway); + var result = await Http.PostAsJsonAsync("api/edge-device", gateway); if (result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor index 0bbece981..20dc7cfca 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor @@ -24,7 +24,7 @@ private async Task DeleteDevice() { - var result = await Http.DeleteAsync($"api/Gateways/{DeviceId}"); + var result = await Http.DeleteAsync($"api/edge-device/{DeviceId}"); if (!result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor index c1f37b4a1..05087bd2f 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor @@ -191,7 +191,7 @@ public async Task LoadDevice() { - Gateway = await Http.GetFromJsonAsync($"api/Gateways/{deviceId}"); + Gateway = await Http.GetFromJsonAsync($"api/edge-device/{deviceId}"); if (Gateway.ConnectionState == "Disconnected") { @@ -203,7 +203,7 @@ public async Task UpdateDevice() { processingUpdate = true; - var result = await Http.PutAsJsonAsync($"api/Gateways/{Gateway.DeviceId}", Gateway); + var result = await Http.PutAsJsonAsync($"api/edge-device/{Gateway.DeviceId}", Gateway); if (result.IsSuccessStatusCode) { @@ -215,7 +215,7 @@ public async Task OnMethod(GatewayModule module, string methodName) { - var result = await Http.PostAsJsonAsync($"api/Gateways/{Gateway.DeviceId}/{module.ModuleName}/{methodName}", module); + var result = await Http.PostAsJsonAsync($"api/edge-device/{Gateway.DeviceId}/{module.ModuleName}/{methodName}", module); var c2dResult = result.Content.ReadFromJsonAsync().Result; @@ -246,11 +246,11 @@ { if (Gateway.Type is null) { - Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/Gateways/{Gateway.DeviceId}/unknown/ConnectionString"); + Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge-device/{Gateway.DeviceId}/unknown/ConnectionString"); } else { - Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/Gateways/{Gateway.DeviceId}/{Gateway.Type}/ConnectionString"); + Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge-device/{Gateway.DeviceId}/{Gateway.Type}/ConnectionString"); } var parameter = new DialogParameters(); diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor index 298b61d5f..b6a121d9e 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor @@ -138,7 +138,7 @@ { try { - result = await Http.GetFromJsonAsync>("api/Gateways"); + result = await Http.GetFromJsonAsync>("api/edge-device"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorDetailPage.razor index 62b10a189..94877943b 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorDetailPage.razor @@ -114,7 +114,7 @@ try { // Sends a GET request to the DevicesController, to retrieve the specific device from Azure IoT Hub - concentrator = await Http.GetFromJsonAsync($"api/concentrators/{DeviceID}"); + concentrator = await Http.GetFromJsonAsync($"api/lorawan/concentrators/{DeviceID}"); } catch (AccessTokenNotAvailableException exception) { @@ -127,7 +127,7 @@ /// public async void SaveDevice() { - var result = await Http.PutAsJsonAsync($"api/concentrators", concentrator); + var result = await Http.PutAsJsonAsync($"api/lorawan/concentrators", concentrator); if (result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor index a90f19d90..2e0cc1155 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor @@ -97,7 +97,7 @@ { try { - concentrators = await Http.GetFromJsonAsync("api/Concentrators"); + concentrators = await Http.GetFromJsonAsync("api/lorawan/concentrators"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/CreateConcentratorPage.razor b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/CreateConcentratorPage.razor index 93d45a0eb..fb5e22d60 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/CreateConcentratorPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/CreateConcentratorPage.razor @@ -87,7 +87,7 @@ { concentrator.DeviceType = "LoRa Concentrator"; // Sends the device to be added to the controller - var response = await Http.PostAsJsonAsync($"api/Concentrators", concentrator); + var response = await Http.PostAsJsonAsync($"api/lorawan/concentrators", concentrator); if (response.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/DeleteConcentratorPage.razor b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/DeleteConcentratorPage.razor index b37d77d76..fe7515d90 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/DeleteConcentratorPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/LoRaWAN/Concentrator/DeleteConcentratorPage.razor @@ -28,7 +28,7 @@ /// private async Task DeleteDevice() { - var response = await Http.DeleteAsync($"api/Concentrators/{deviceId}"); + var response = await Http.DeleteAsync($"api/lorawan/concentrators/{deviceId}"); // Prompts a snack bar to inform if the action was successful // TODO : Deal more effectively with error/success messages diff --git a/src/AzureIoTHub.Portal/Client/Program.cs b/src/AzureIoTHub.Portal/Client/Program.cs index bf75be8b6..d9259f513 100644 --- a/src/AzureIoTHub.Portal/Client/Program.cs +++ b/src/AzureIoTHub.Portal/Client/Program.cs @@ -42,7 +42,7 @@ private static async Task ConfigureOidc(WebAssemblyHostBuilder builder) { using (var httpClient = new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }) { - var settings = await httpClient.GetFromJsonAsync("OIDCSettings"); + var settings = await httpClient.GetFromJsonAsync("api/settings/oidc"); builder.Services.AddOidcAuthentication(options => { diff --git a/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs index c9bf33b2a..545bbf22e 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs @@ -17,8 +17,9 @@ namespace AzureIoTHub.Portal.Server.Controllers using Microsoft.Azure.Devices.Shared; using Microsoft.Extensions.Logging; - [Route("api/[controller]")] [ApiController] + [Route("api/lorawan/concentrators")] + [ApiExplorerSettings(GroupName = "LoRa WAN")] public class ConcentratorsController : ControllerBase { private readonly IDeviceService devicesService; diff --git a/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs index 02199919d..91bda1f64 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs @@ -15,7 +15,8 @@ namespace AzureIoTHub.Portal.Server.Controllers using Newtonsoft.Json.Linq; [ApiController] - [Route("api/[controller]")] + [Route("api/edge-config")] + [ApiExplorerSettings(GroupName = "IoT Edge")] public class ConfigsController : ControllerBase { private readonly ConfigsServices configService; diff --git a/src/AzureIoTHub.Portal/Server/Controllers/CommandsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelCommandsController.cs similarity index 88% rename from src/AzureIoTHub.Portal/Server/Controllers/CommandsController.cs rename to src/AzureIoTHub.Portal/Server/Controllers/DeviceModelCommandsController.cs index 18eca2228..fcb509cf2 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/CommandsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelCommandsController.cs @@ -11,13 +11,14 @@ namespace AzureIoTHub.Portal.Server.Controllers using Microsoft.AspNetCore.Mvc; [ApiController] - [Route("api/[controller]")] - public class CommandsController : ControllerBase + [Route("api/models/{modelId}/commands")] + [ApiExplorerSettings(GroupName = "Device Models")] + public class DeviceModelCommandsController : ControllerBase { private readonly ITableClientFactory tableClientFactory; private readonly IDeviceModelCommandMapper deviceModelCommandMapper; - public CommandsController( + public DeviceModelCommandsController( IDeviceModelCommandMapper deviceModelCommandMapper, ITableClientFactory tableClientFactory) { @@ -29,7 +30,7 @@ public CommandsController( /// Add a command to an Azure DataTable. /// /// Operation status. - [HttpPost("{modelId}")] + [HttpPost] public async Task Post(string modelId, DeviceModelCommand command) { TableEntity entity = new TableEntity() @@ -48,7 +49,7 @@ await this.tableClientFactory /// Delete a command from an Azure DataTable. /// /// Operation status. - [HttpDelete("{modelId}/{commandId}")] + [HttpDelete("{commandId}")] public async Task Delete(string modelId, string commandId) { var result = await this.tableClientFactory.GetDeviceCommands().DeleteEntityAsync(modelId, commandId); diff --git a/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelsController.cs index 29efc13e7..4fd7cbcf3 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/DeviceModelsController.cs @@ -18,7 +18,8 @@ namespace AzureIoTHub.Portal.Server.Controllers using Microsoft.AspNetCore.Mvc; [ApiController] - [Route("api/[controller]")] + [Route("api/models")] + [ApiExplorerSettings(GroupName = "Device Models")] public class DeviceModelsController : ControllerBase { private const string DefaultPartitionKey = "0"; diff --git a/src/AzureIoTHub.Portal/Server/Controllers/DevicesController.cs b/src/AzureIoTHub.Portal/Server/Controllers/DevicesController.cs index 938495dd7..7d3e0a327 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/DevicesController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/DevicesController.cs @@ -22,7 +22,8 @@ namespace AzureIoTHub.Portal.Server.Controllers using Microsoft.Extensions.Logging; [ApiController] - [Route("api/[controller]")] + [Route("api/devices")] + [ApiExplorerSettings(GroupName = "IoT Devices")] public class DevicesController : ControllerBase { private readonly ILogger logger; diff --git a/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs b/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs index 8cbabce35..cd7782003 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs @@ -22,7 +22,8 @@ namespace AzureIoTHub.Portal.Server.Controllers using Newtonsoft.Json.Linq; [ApiController] - [Route("api/[controller]")] + [Route("api/edge-device")] + [ApiExplorerSettings(GroupName = "IoT Edge")] public class GatewaysController : ControllerBase { private readonly ILogger logger; diff --git a/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs index 7b73c1d74..49948dfe3 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs @@ -11,8 +11,9 @@ namespace AzureIoTHub.Portal.Server.Controllers [ApiController] [AllowAnonymous] - [Route("[controller]")] + [Route("/api/settings")] [Produces("application/json")] + [ApiExplorerSettings(GroupName = "Portal Settings")] public class OIDCSettingsController : ControllerBase { private readonly ClientApiIndentityOptions configuration; @@ -28,7 +29,7 @@ public OIDCSettingsController(IOptions configuration) /// The portal OIDC settnigs. /// Returns the OIDC settings. /// Internal server error. - [HttpGet(Name = "GET Settings")] + [HttpGet("oidc", Name = "GET OIDC")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public IActionResult GetOIDCSettings() diff --git a/src/AzureIoTHub.Portal/Server/Startup.cs b/src/AzureIoTHub.Portal/Server/Startup.cs index ef0cb86fb..31d4c8473 100644 --- a/src/AzureIoTHub.Portal/Server/Startup.cs +++ b/src/AzureIoTHub.Portal/Server/Startup.cs @@ -142,6 +142,9 @@ public void ConfigureServices(IServiceCollection services) // using System.Reflection; var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; opts.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + + opts.TagActionsBy(api => new[] { api.GroupName }); + opts.DocInclusionPredicate((name, api) => true); }); } From ccd943d3eb73152f337dfa8d553a054765255438 Mon Sep 17 00:00:00 2001 From: "Beaugrand, Kevin" Date: Sun, 13 Feb 2022 10:30:45 +0100 Subject: [PATCH 2/3] Rename controllers classes --- .../Controllers/ConcentratorsControllerTests.cs | 8 ++++---- .../Controllers/GatewaysControllerTests.cs | 8 ++++---- ...nfigsController.cs => EdgeConfigurationsController.cs} | 4 ++-- .../{GatewaysController.cs => EdgeDevicesController.cs} | 8 ++++---- ...orsController.cs => LoRaWANConcentratorsController.cs} | 8 ++++---- .../{OIDCSettingsController.cs => SettingsController.cs} | 4 ++-- .../Server/Properties/GlobalSuppressions.cs | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) rename src/AzureIoTHub.Portal/Server/Controllers/{ConfigsController.cs => EdgeConfigurationsController.cs} (97%) rename src/AzureIoTHub.Portal/Server/Controllers/{GatewaysController.cs => EdgeDevicesController.cs} (98%) rename src/AzureIoTHub.Portal/Server/Controllers/{ConcentratorsController.cs => LoRaWANConcentratorsController.cs} (95%) rename src/AzureIoTHub.Portal/Server/Controllers/{OIDCSettingsController.cs => SettingsController.cs} (89%) diff --git a/src/AzureIoTHub.Portal.Server.Tests/Controllers/ConcentratorsControllerTests.cs b/src/AzureIoTHub.Portal.Server.Tests/Controllers/ConcentratorsControllerTests.cs index 237601448..74ec9186e 100644 --- a/src/AzureIoTHub.Portal.Server.Tests/Controllers/ConcentratorsControllerTests.cs +++ b/src/AzureIoTHub.Portal.Server.Tests/Controllers/ConcentratorsControllerTests.cs @@ -23,22 +23,22 @@ public class ConcentratorsControllerTests private Mock mockRouterManager; private Mock mockConcentratorTwinMapper; private Mock mockDeviceService; - private Mock> mockLogger; + private Mock> mockLogger; [SetUp] public void SetUp() { this.mockRepository = new MockRepository(MockBehavior.Strict); - this.mockLogger = this.mockRepository.Create>(); + this.mockLogger = this.mockRepository.Create>(); this.mockRouterManager = this.mockRepository.Create(); this.mockConcentratorTwinMapper = this.mockRepository.Create(); this.mockDeviceService = this.mockRepository.Create(); } - private ConcentratorsController CreateController() + private LoRaWANConcentratorsController CreateController() { - return new ConcentratorsController( + return new LoRaWANConcentratorsController( this.mockLogger.Object, this.mockDeviceService.Object, this.mockRouterManager.Object, diff --git a/src/AzureIoTHub.Portal.Server.Tests/Controllers/GatewaysControllerTests.cs b/src/AzureIoTHub.Portal.Server.Tests/Controllers/GatewaysControllerTests.cs index de55b012a..41487838d 100644 --- a/src/AzureIoTHub.Portal.Server.Tests/Controllers/GatewaysControllerTests.cs +++ b/src/AzureIoTHub.Portal.Server.Tests/Controllers/GatewaysControllerTests.cs @@ -21,7 +21,7 @@ public class GatewaysControllerTests private MockRepository mockRepository; private Mock mockConfiguration; - private Mock> mockLogger; + private Mock> mockLogger; private Mock mockRegistryManager; private Mock mockConnectionStringManager; private Mock mockDeviceService; @@ -32,15 +32,15 @@ public void SetUp() this.mockRepository = new MockRepository(MockBehavior.Strict); this.mockConfiguration = this.mockRepository.Create(); - this.mockLogger = this.mockRepository.Create>(); + this.mockLogger = this.mockRepository.Create>(); this.mockRegistryManager = this.mockRepository.Create(); this.mockConnectionStringManager = this.mockRepository.Create(); this.mockDeviceService = this.mockRepository.Create(); } - private GatewaysController CreateGatewaysController() + private EdgeDevicesController CreateGatewaysController() { - return new GatewaysController( + return new EdgeDevicesController( this.mockConfiguration.Object, this.mockLogger.Object, this.mockRegistryManager.Object, diff --git a/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs similarity index 97% rename from src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs rename to src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs index 91bda1f64..7846f3686 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/ConfigsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs @@ -17,11 +17,11 @@ namespace AzureIoTHub.Portal.Server.Controllers [ApiController] [Route("api/edge-config")] [ApiExplorerSettings(GroupName = "IoT Edge")] - public class ConfigsController : ControllerBase + public class EdgeConfigurationsController : ControllerBase { private readonly ConfigsServices configService; - public ConfigsController(ConfigsServices configService) + public EdgeConfigurationsController(ConfigsServices configService) { this.configService = configService; } diff --git a/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs b/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs similarity index 98% rename from src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs rename to src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs index cd7782003..cb5a45583 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/GatewaysController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs @@ -24,18 +24,18 @@ namespace AzureIoTHub.Portal.Server.Controllers [ApiController] [Route("api/edge-device")] [ApiExplorerSettings(GroupName = "IoT Edge")] - public class GatewaysController : ControllerBase + public class EdgeDevicesController : ControllerBase { - private readonly ILogger logger; + private readonly ILogger logger; private readonly RegistryManager registryManager; private readonly IConfiguration configuration; private readonly IDeviceService devicesService; private readonly IConnectionStringManager connectionStringManager; - public GatewaysController( + public EdgeDevicesController( IConfiguration configuration, - ILogger logger, + ILogger logger, RegistryManager registryManager, IConnectionStringManager connectionStringManager, IDeviceService service) diff --git a/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/LoRaWANConcentratorsController.cs similarity index 95% rename from src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs rename to src/AzureIoTHub.Portal/Server/Controllers/LoRaWANConcentratorsController.cs index 545bbf22e..3e99dc9c4 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/ConcentratorsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/LoRaWANConcentratorsController.cs @@ -20,15 +20,15 @@ namespace AzureIoTHub.Portal.Server.Controllers [ApiController] [Route("api/lorawan/concentrators")] [ApiExplorerSettings(GroupName = "LoRa WAN")] - public class ConcentratorsController : ControllerBase + public class LoRaWANConcentratorsController : ControllerBase { private readonly IDeviceService devicesService; private readonly IConcentratorTwinMapper concentratorTwinMapper; private readonly IRouterConfigManager routerConfigManager; - private readonly ILogger logger; + private readonly ILogger logger; - public ConcentratorsController( - ILogger logger, + public LoRaWANConcentratorsController( + ILogger logger, IDeviceService devicesService, IRouterConfigManager routerConfigManager, IConcentratorTwinMapper concentratorTwinMapper) diff --git a/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/SettingsController.cs similarity index 89% rename from src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs rename to src/AzureIoTHub.Portal/Server/Controllers/SettingsController.cs index 49948dfe3..58cea245e 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/OIDCSettingsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/SettingsController.cs @@ -14,11 +14,11 @@ namespace AzureIoTHub.Portal.Server.Controllers [Route("/api/settings")] [Produces("application/json")] [ApiExplorerSettings(GroupName = "Portal Settings")] - public class OIDCSettingsController : ControllerBase + public class SettingsController : ControllerBase { private readonly ClientApiIndentityOptions configuration; - public OIDCSettingsController(IOptions configuration) + public SettingsController(IOptions configuration) { this.configuration = configuration.Value; } diff --git a/src/AzureIoTHub.Portal/Server/Properties/GlobalSuppressions.cs b/src/AzureIoTHub.Portal/Server/Properties/GlobalSuppressions.cs index 9dd18d3b5..fbfcb38bb 100644 --- a/src/AzureIoTHub.Portal/Server/Properties/GlobalSuppressions.cs +++ b/src/AzureIoTHub.Portal/Server/Properties/GlobalSuppressions.cs @@ -4,4 +4,4 @@ using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "ErrorModel is nested to the ErrorPage", Scope = "type", Target = "~T:AzureIoTHub.Portal.Server.Pages.ErrorModel")] -[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1629:Documentation text should end with a period", Justification = "SwashBuckle documentation need no period in remarks.", Scope = "member", Target = "~M:AzureIoTHub.Portal.Server.Controllers.OIDCSettingsController.GetOIDCSettings~Microsoft.AspNetCore.Mvc.IActionResult")] +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1629:Documentation text should end with a period", Justification = "SwashBuckle documentation need no period in remarks.", Scope = "member", Target = "~M:AzureIoTHub.Portal.Server.Controllers.SettingsController.GetOIDCSettings~Microsoft.AspNetCore.Mvc.IActionResult")] From 3b028ba757cbb2ad2af245d352805dc7776d14d7 Mon Sep 17 00:00:00 2001 From: "Beaugrand, Kevin" Date: Sun, 13 Feb 2022 10:49:29 +0100 Subject: [PATCH 3/3] Review IoT Edge routes --- .../Client/Pages/Configurations/ConfigDetail.razor | 4 ++-- .../Client/Pages/Configurations/Configs.razor | 8 ++++---- .../Edge_Devices/CreateEdgeDeviceDialog.razor | 4 ++-- .../EdgeDeviceDeleteConfirmationDialog.razor | 2 +- .../Pages/Edge_Devices/EdgeDeviceDetailPage.razor | 14 +++++++------- .../Pages/Edge_Devices/EdgeDeviceListPage.razor | 8 ++++---- .../Pages/Edge_Devices/ModuleLogsDialog.razor | 2 +- src/AzureIoTHub.Portal/Client/Shared/NavMenu.razor | 4 ++-- .../Controllers/EdgeConfigurationsController.cs | 2 +- .../Server/Controllers/EdgeDevicesController.cs | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor b/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor index bc46d5bef..5e4f0ae95 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Configurations/ConfigDetail.razor @@ -1,4 +1,4 @@ -@page "/configdetail/{ConfigurationID}" +@page "/edge/configurations/{ConfigurationID}" @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using AzureIoTHub.Portal.Shared.Models @@ -132,7 +132,7 @@ try { // Sends a GET request to the ConfigController, to retrieve a specific deployment from Azure IoT Hub - Config = await Http.GetFromJsonAsync($"api/settings/oidc/{ConfigurationID}"); + Config = await Http.GetFromJsonAsync($"api/edge/configurations/{ConfigurationID}"); ConditionOwner = RetrieveCondition("owner"); ConditionEnv = RetrieveCondition("env"); ConditionType = RetrieveCondition("type"); diff --git a/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor b/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor index b90a1e9c9..d23b7bf84 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Configurations/Configs.razor @@ -1,4 +1,4 @@ -@page "/configurations" +@page "/edge/configurations" @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using AzureIoTHub.Portal.Shared.Models @@ -45,7 +45,7 @@ - @context.ConfigurationID + @context.ConfigurationID @context.Conditions @@ -61,7 +61,7 @@ @context.Priority @context.CreationDate - + @@ -93,7 +93,7 @@ { try { - result = await Http.GetFromJsonAsync("api/settings/oidc"); + result = await Http.GetFromJsonAsync("api/edge/configurations"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor index fb5ac19fb..507143960 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/CreateEdgeDeviceDialog.razor @@ -1,4 +1,4 @@ -@page "/edge-devices/add" +@page "/edge/devices/add" @using Microsoft.AspNetCore.Authorization @using AzureIoTHub.Portal.Shared.Models; @@ -61,7 +61,7 @@ private async Task OnValidation() { - var result = await Http.PostAsJsonAsync("api/edge-device", gateway); + var result = await Http.PostAsJsonAsync("api/edge/device", gateway); if (result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor index 20dc7cfca..f90a5017c 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDeleteConfirmationDialog.razor @@ -24,7 +24,7 @@ private async Task DeleteDevice() { - var result = await Http.DeleteAsync($"api/edge-device/{DeviceId}"); + var result = await Http.DeleteAsync($"api/edge/device/{DeviceId}"); if (!result.IsSuccessStatusCode) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor index 05087bd2f..048e552ca 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceDetailPage.razor @@ -1,4 +1,4 @@ -@page "/edge-device/detail/{deviceId}" +@page "/edge/devices/{deviceId}" @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using AzureIoTHub.Portal.Shared.Models @@ -191,7 +191,7 @@ public async Task LoadDevice() { - Gateway = await Http.GetFromJsonAsync($"api/edge-device/{deviceId}"); + Gateway = await Http.GetFromJsonAsync($"api/edge/device/{deviceId}"); if (Gateway.ConnectionState == "Disconnected") { @@ -203,7 +203,7 @@ public async Task UpdateDevice() { processingUpdate = true; - var result = await Http.PutAsJsonAsync($"api/edge-device/{Gateway.DeviceId}", Gateway); + var result = await Http.PutAsJsonAsync($"api/edge/device/{Gateway.DeviceId}", Gateway); if (result.IsSuccessStatusCode) { @@ -215,7 +215,7 @@ public async Task OnMethod(GatewayModule module, string methodName) { - var result = await Http.PostAsJsonAsync($"api/edge-device/{Gateway.DeviceId}/{module.ModuleName}/{methodName}", module); + var result = await Http.PostAsJsonAsync($"api/edge/device/{Gateway.DeviceId}/{module.ModuleName}/{methodName}", module); var c2dResult = result.Content.ReadFromJsonAsync().Result; @@ -246,11 +246,11 @@ { if (Gateway.Type is null) { - Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge-device/{Gateway.DeviceId}/unknown/ConnectionString"); + Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge/device/{Gateway.DeviceId}/unknown/ConnectionString"); } else { - Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge-device/{Gateway.DeviceId}/{Gateway.Type}/ConnectionString"); + Gateway.SymmetricKey = await this.Http.GetStringAsync($"api/edge/device/{Gateway.DeviceId}/{Gateway.Type}/ConnectionString"); } var parameter = new DialogParameters(); @@ -290,7 +290,7 @@ return; } - NavigationManager.NavigateTo("/edge-devices"); + NavigationManager.NavigateTo("/edge/devices"); } public class CustomStringToBoolConverter : BoolConverter diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor index b6a121d9e..9d8997109 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/EdgeDeviceListPage.razor @@ -1,4 +1,4 @@ -@page "/edge-devices" +@page "/edge/devices" @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using AzureIoTHub.Portal.Shared.Models @@ -87,7 +87,7 @@ - @context.DeviceId + @context.DeviceId @if (context.Status == "Enabled") @@ -103,7 +103,7 @@ @context.Type @context.NbDevices - + @@ -138,7 +138,7 @@ { try { - result = await Http.GetFromJsonAsync>("api/edge-device"); + result = await Http.GetFromJsonAsync>("api/edge/device"); } catch (AccessTokenNotAvailableException exception) { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/ModuleLogsDialog.razor b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/ModuleLogsDialog.razor index 473514067..109726208 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/ModuleLogsDialog.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Edge_Devices/ModuleLogsDialog.razor @@ -1,4 +1,4 @@ -@page "/edge-devices/logs" +@page "/edge/devices/logs" @using AzureIoTHub.Portal.Shared.Models @using Newtonsoft.Json; diff --git a/src/AzureIoTHub.Portal/Client/Shared/NavMenu.razor b/src/AzureIoTHub.Portal/Client/Shared/NavMenu.razor index a913968fc..3af4cc442 100644 --- a/src/AzureIoTHub.Portal/Client/Shared/NavMenu.razor +++ b/src/AzureIoTHub.Portal/Client/Shared/NavMenu.razor @@ -9,8 +9,8 @@ IoT Edge - Devices - Configuration + Devices + Configuration LoRaWAN Management Concentrators diff --git a/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs b/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs index 7846f3686..c30c1f01b 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/EdgeConfigurationsController.cs @@ -15,7 +15,7 @@ namespace AzureIoTHub.Portal.Server.Controllers using Newtonsoft.Json.Linq; [ApiController] - [Route("api/edge-config")] + [Route("api/edge/configurations")] [ApiExplorerSettings(GroupName = "IoT Edge")] public class EdgeConfigurationsController : ControllerBase { diff --git a/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs b/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs index cb5a45583..c3fb10fec 100644 --- a/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs +++ b/src/AzureIoTHub.Portal/Server/Controllers/EdgeDevicesController.cs @@ -22,7 +22,7 @@ namespace AzureIoTHub.Portal.Server.Controllers using Newtonsoft.Json.Linq; [ApiController] - [Route("api/edge-device")] + [Route("api/edge/device")] [ApiExplorerSettings(GroupName = "IoT Edge")] public class EdgeDevicesController : ControllerBase {