Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheduler and plannings management (#3255) #3256

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/IoTHub.Portal.Application/Helpers/ConfigHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
ModuleName = module.Name,
Image = module.Value["settings"]?["image"]?.Value<string>(),
ContainerCreateOptions = module.Value["settings"]?["createOptions"]?.Value<string>(),
StartupOrder = module.Value["settings"]?["startupOrder"]?.Value<int>() ?? 0,
Status = module.Value["status"]?.Value<string>(),
};

Expand Down Expand Up @@ -229,6 +230,11 @@
edgeAgentPropertiesDesired.SystemModules.EdgeAgent.Settings.CreateOptions = edgeModel.SystemModules.Single(x => x.Name == "edgeAgent").ContainerCreateOptions;
}

if (edgeModel.SystemModules.Single(x => x.Name == "edgeAgent").StartupOrder > 0)
{
edgeAgentPropertiesDesired.SystemModules.EdgeAgent.Settings.StartupOrder = edgeModel.SystemModules.Single(x => x.Name == "edgeAgent").StartupOrder;
}

if (!string.IsNullOrEmpty(edgeModel.SystemModules.Single(x => x.Name == "edgeHub").Image))
{
edgeAgentPropertiesDesired.SystemModules.EdgeHub.Settings.Image = edgeModel.SystemModules.Single(x => x.Name == "edgeHub").Image;
Expand All @@ -241,6 +247,11 @@
edgeAgentPropertiesDesired.SystemModules.EdgeHub.Settings.CreateOptions = edgeModel.SystemModules.Single(x => x.Name == "edgeHub").ContainerCreateOptions;
}

if (edgeModel.SystemModules.Single(x => x.Name == "edgeHub").StartupOrder > 0)
{
edgeAgentPropertiesDesired.SystemModules.EdgeHub.Settings.StartupOrder = edgeModel.SystemModules.Single(x => x.Name == "edgeHub").StartupOrder;
}

Check warning on line 253 in src/IoTHub.Portal.Application/Helpers/ConfigHelper.cs

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Application/Helpers/ConfigHelper.cs#L251-L253

Added lines #L251 - L253 were not covered by tests

foreach (var item in edgeModel.SystemModules.Single(x => x.Name == "edgeAgent").EnvironmentVariables)
{
edgeAgentPropertiesDesired.SystemModules.EdgeAgent.EnvironmentVariables?.Add(item.Name, new EnvironmentVariable() { EnvValue = item.Value });
Expand All @@ -262,7 +273,8 @@
Settings = new ModuleSettings()
{
Image = module.Image,
CreateOptions = module.ContainerCreateOptions
CreateOptions = module.ContainerCreateOptions,
StartupOrder = module.StartupOrder,
},
RestartPolicy = "always",
EnvironmentVariables = new Dictionary<string, EnvironmentVariable>()
Expand Down
6 changes: 6 additions & 0 deletions src/IoTHub.Portal.Application/Mappers/DeviceProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public DeviceProfile()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.DeviceID))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.DeviceName))
.ForMember(dest => dest.DeviceModelId, opts => opts.MapFrom(src => src.ModelId))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.LayerId))
.ForMember(dest => dest.Tags, opts => opts.MapFrom(src => src.Tags.Select(pair => new DeviceTagValue
{
Name = pair.Key,
Expand All @@ -25,12 +26,14 @@ public DeviceProfile()
.ForMember(dest => dest.DeviceID, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.DeviceName, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.ModelId, opts => opts.MapFrom(src => src.DeviceModelId))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.LayerId))
.ForMember(dest => dest.Tags, opts => opts.MapFrom(src => src.Tags.ToDictionary(tag => tag.Name, tag => tag.Value)));

_ = CreateMap<Twin, Device>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.DeviceId))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Tags["deviceName"]))
.ForMember(dest => dest.DeviceModelId, opts => opts.MapFrom(src => src.Tags["modelId"]))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.Tags.Contains("layerId") ? src.Tags["layerId"] : null))
.ForMember(dest => dest.Version, opts => opts.MapFrom(src => src.Version))
.ForMember(dest => dest.IsConnected, opts => opts.MapFrom(src => src.ConnectionState == Microsoft.Azure.Devices.DeviceConnectionState.Connected))
.ForMember(dest => dest.IsEnabled, opts => opts.MapFrom(src => src.Status == Microsoft.Azure.Devices.DeviceStatus.Enabled))
Expand All @@ -42,6 +45,7 @@ public DeviceProfile()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.DeviceID))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.DeviceName))
.ForMember(dest => dest.DeviceModelId, opts => opts.MapFrom(src => src.ModelId))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.LayerId))
.ForMember(dest => dest.Tags, opts => opts.MapFrom(src => src.Tags.Select(pair => new DeviceTagValue
{
Name = pair.Key,
Expand All @@ -52,12 +56,14 @@ public DeviceProfile()
.ForMember(dest => dest.DeviceID, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.DeviceName, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.ModelId, opts => opts.MapFrom(src => src.DeviceModelId))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.LayerId))
.ForMember(dest => dest.Tags, opts => opts.MapFrom(src => src.Tags.ToDictionary(tag => tag.Name, tag => tag.Value)));

_ = CreateMap<Twin, LorawanDevice>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.DeviceId))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Tags["deviceName"]))
.ForMember(dest => dest.DeviceModelId, opts => opts.MapFrom(src => src.Tags["modelId"]))
.ForMember(dest => dest.LayerId, opts => opts.MapFrom(src => src.Tags.Contains("layerId") ? src.Tags["layerId"] : null))
.ForMember(dest => dest.Version, opts => opts.MapFrom(src => src.Version))
.ForMember(dest => dest.IsConnected, opts => opts.MapFrom(src => src.ConnectionState == Microsoft.Azure.Devices.DeviceConnectionState.Connected))
.ForMember(dest => dest.IsEnabled, opts => opts.MapFrom(src => src.Status == Microsoft.Azure.Devices.DeviceStatus.Enabled))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@
</MudRadioGroup>

</MudItem>
<MudItem xs="12" md="6">
<MudText>Connection state</MudText>
<MudRadioGroup @bind-SelectedOption="@searchState" Style="display:flex;align-items:baseline">
<MudItem md="4" sm="12">
<MudRadio Option=@("true") Color="Color.Primary" id="searchStateConnected">Connected</MudRadio>
</MudItem>
<MudItem md="4" sm="12">
<MudRadio Option=@("false") Color="Color.Primary" id="searchStateDisconnected">Disconnected</MudRadio>
</MudItem>
<MudItem md="4" sm="12">
<MudRadio Option=@("") Color="Color.Secondary" id="searchStateAll">All</MudRadio>
</MudItem>
</MudRadioGroup>
</MudItem>
</MudGrid>

<MudItem xs="12">
Expand Down
69 changes: 53 additions & 16 deletions src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
@using IoTHub.Portal.Models
@using IoTHub.Portal.Models.v10
@using IoTHub.Portal.Shared.Models.v10
@using IoTHub.Portal.Client.Validators
@using System.Net.Http.Headers
@using IoTHub.Portal.Shared.Constants
@using IoTHub.Portal.Client.Models
@using IoTHub.Portal.Shared.Models
@using IoTHub.Portal.Shared.Models.v10.Filters
@using IoTHub.Portal.Models.v10.LoRaWAN
@using IoTHub.Portal.Client.Helpers

@attribute [Authorize]
@attribute [Authorize]
@inject NavigationManager NavigationManager
@inject PortalSettings Portal

Expand All @@ -25,6 +13,10 @@
<MudText Typo="Typo.h5" Color="Color.Primary" Class="mb-4">
@mode Planning
<MudButton Variant="Variant.Filled" Class="mx-1" Color="Color.Primary" OnClick="Save" id="saveButton" Disabled="isProcessing">Save</MudButton>
@if (mode == "Edit")
{
<MudButton Variant="Variant.Filled" Class="mx-1" Color="Color.Error" OnClick="DeletePlanning" id="deleteButton" Disabled="isProcessing">Delete planning</MudButton>
}
</MudText>
@if (!isProcessing)
{
Expand Down Expand Up @@ -85,7 +77,7 @@
</MudSelect>
</MudTd>
<MudTd DataLabel="Delete" Style="text-align: center">
<MudIconButton Color="Color.Default" Class="deleteRouteButton" OnClick="( () => DeleteSchedule(ContextSchedule))" Icon="@Icons.Material.Filled.Delete" Size="Size.Medium"></MudIconButton>
<MudIconButton Color="Color.Default" Class="deleteRouteButton" id="deleteScheduleButton" OnClick="( () => DeleteSchedule(ContextSchedule))" Icon="@Icons.Material.Filled.Delete" Size="Size.Medium"></MudIconButton>
</MudTd>
</RowTemplate>
<FooterContent>
Expand Down Expand Up @@ -184,10 +176,29 @@
<MudPaper Class="overflow-y-auto" Elevation="0">
<MudTreeView Items="@Layers">
<ItemTemplate>
<MudTreeViewItem @bind-Expanded="@context.IsExpanded" Items="@context.Children">
<MudTreeViewItem id="selectLayer" @bind-Expanded="@context.IsExpanded" Items="@context.Children">
<Content>
<MudTreeViewItemToggleButton @bind-Expanded="@context.IsExpanded" Visible="@(context.Children.Count() != 0)" />
<MudCheckBox T="bool?" Checked="@(context.LayerData.Planning == planning.Id)" ValueChanged="@(() => CheckedChanged(context))"></MudCheckBox>

@if ((context.LayerData.Planning != null && context.LayerData.Planning != "None" && context.LayerData.Planning == planning.Id))
{
<MudTooltip Text="Already registered">
<MudIconButton Color="Color.Success" Icon="@Icons.Material.Filled.CheckBox" Size="Size.Medium" @onclick="() => CheckedChanged(context)"></MudIconButton>

Check warning on line 186 in src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor#L186

Added line #L186 was not covered by tests
</MudTooltip>
}
else if (context.LayerData.Planning != null && context.LayerData.Planning != "None" && context.LayerData.Planning != planning.Id)
{
<MudTooltip Text="Registered on other planning">
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.IndeterminateCheckBox" Size="Size.Medium" @onclick="() => CheckedChanged(context)"></MudIconButton>

Check warning on line 192 in src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor#L192

Added line #L192 was not covered by tests
</MudTooltip>
}
else
{
<MudTooltip Text="Add layer">
<MudIconButton Color="Color.Default" Icon="@Icons.Material.Filled.CheckBoxOutlineBlank" Size="Size.Medium" @onclick="() => CheckedChanged(context)"></MudIconButton>

Check warning on line 198 in src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor#L198

Added line #L198 was not covered by tests
</MudTooltip>
}

<MudText>@context.LayerData.Name</MudText>
</Content>
</MudTreeViewItem>
Expand Down Expand Up @@ -418,4 +429,30 @@
return "";
}

/// <summary>
/// Prompts a pop-up windows to confirm the planning's deletion.
/// </summary>
/// <returns></returns>
private async Task DeletePlanning()
{
isProcessing = true;

var parameters = new DialogParameters
{
{"planningID", planning.Id},
{"planningName", planning.Name}
};
var result = await DialogService.Show<DeletePlanningDialog>("Confirm Deletion", parameters).Result;

isProcessing = false;

if (result.Canceled)
{
return;
}

// Go back to the list of plannings
NavigationManager.NavigateTo($"/planning");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@
<DialogContent>
<MudContainer Style="max-height: 600px; overflow-y: scroll">
<MudGrid>
<MudItem xs="12" md="6">
<MudItem xs="12" md="4">
<MudTextField @bind-Value="@currentModuleName"
id=@nameof(IoTEdgeModule.ModuleName)
Label="Module name"
Variant="Variant.Outlined"
For="@(() => Module.ModuleName)"
Required="true"/>
</MudItem>
<MudItem xs="12" md="2">
<MudTextField @bind-Value="@currentStartupOrder"
id=@nameof(IoTEdgeModule.StartupOrder)
Label="Startup Order"
Variant="Variant.Outlined"
For="@(() => Module.StartupOrder)"
Required="false" />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField @bind-Value="@currentImage"
id=@nameof(IoTEdgeModule.Image)
Expand Down Expand Up @@ -87,6 +95,7 @@
private string currentImage = default!;
private string currentContainerCreateOptions = default!;
private string currentNumVersion = "1.0.0";
private int currentStartupOrder;

private List<IoTEdgeModuleEnvironmentVariable> currentEnvironmentVariables = new();
private List<IoTEdgeModuleTwinSetting> currentModuleIdentityTwinSettings = new();
Expand All @@ -103,6 +112,7 @@
currentImage = Module.Image;
currentContainerCreateOptions = Module.ContainerCreateOptions;
currentNumVersion = Module.Version;
currentStartupOrder = Module.StartupOrder;
currentEnvironmentVariables = new List<IoTEdgeModuleEnvironmentVariable>(Module.EnvironmentVariables.ToArray());
currentModuleIdentityTwinSettings = new List<IoTEdgeModuleTwinSetting>(Module.ModuleIdentityTwinSettings.ToArray());
currentCommands = new List<IoTEdgeModuleCommand>(Module.Commands.ToArray());
Expand All @@ -115,6 +125,7 @@
Module.ModuleName = currentModuleName;
Module.Image = currentImage;
Module.ContainerCreateOptions = currentContainerCreateOptions;
Module.StartupOrder = currentStartupOrder;

if (Portal.CloudProvider.Equals(CloudProviders.Azure)) { Module.Version = " "; }
else { Module.Version = currentNumVersion; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
<DialogContent>
<MudContainer Style="max-height: 600px; overflow-y: scroll">
<MudGrid>
<MudItem xs="12" md="6">
<MudItem xs="12" md="4">
<MudTextField @bind-Value="@currentModuleName"
id=@nameof(EdgeModelSystemModule.Name)
Label="Module name"
Variant="Variant.Outlined"
For="@(()=> Module.Name)"
Required="true" Disabled/>
</MudItem>
<MudItem xs="12" md="2">
<MudTextField @bind-Value="@currentStartupOrder"
id=@nameof(EdgeModelSystemModule.StartupOrder)
Label="Startup Order"
Variant="Variant.Outlined"
For="@(() => Module.StartupOrder)"
Required="false" />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField @bind-Value="@currentImage"
id=@nameof(EdgeModelSystemModule.Image)
Expand Down Expand Up @@ -45,7 +53,7 @@
</DialogActions>
</MudDialog>

@code {
@code {
[CascadingParameter]
MudDialogInstance MudDialog { get; set; } = default!;

Expand All @@ -55,6 +63,7 @@
private string currentModuleName = default!;
private string currentImage = default!;
private string currentContainerCreateOptions = default!;
private int currentStartupOrder;

private List<IoTEdgeModuleEnvironmentVariable> currentEnvironmentVariables = new();

Expand All @@ -67,6 +76,7 @@
currentModuleName = Module.Name;
currentImage = Module.Image;
currentContainerCreateOptions = Module.ContainerCreateOptions;
currentStartupOrder = Module.StartupOrder;
currentEnvironmentVariables = new List<IoTEdgeModuleEnvironmentVariable>(Module.EnvironmentVariables.ToArray());
await Task.Delay(0);
IsLoading = false;
Expand All @@ -77,6 +87,7 @@
Module.Name = currentModuleName;
Module.Image = currentImage;
Module.ContainerCreateOptions = currentContainerCreateOptions;
Module.StartupOrder = currentStartupOrder;
Module.EnvironmentVariables = new List<IoTEdgeModuleEnvironmentVariable>(currentEnvironmentVariables.ToArray());
MudDialog.Close(DialogResult.Ok(true));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@
if (device.LayerId != null && device.LayerId == InitLayer.Id)
{
if (DeviceRemoveList.Contains(device.DeviceID)) DeviceRemoveList.Remove(device.DeviceID);
else DeviceRemoveList.Add(device.DeviceID);
else
{
DeviceList.Remove(device.DeviceID);
DeviceRemoveList.Add(device.DeviceID);
device.LayerId = null;
}

Check warning on line 178 in src/IoTHub.Portal.Client/Dialogs/Layer/LinkDeviceLayerDialog.razor

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Client/Dialogs/Layer/LinkDeviceLayerDialog.razor#L174-L178

Added lines #L174 - L178 were not covered by tests
}
else
{
Expand Down Expand Up @@ -223,6 +228,7 @@
deviceDetails.IsConnected = device.IsConnected;
deviceDetails.IsEnabled = device.IsEnabled;
deviceDetails.StatusUpdatedTime = device.StatusUpdatedTime;
deviceDetails.LastActivityTime = device.LastActivityTime;

Check warning on line 231 in src/IoTHub.Portal.Client/Dialogs/Layer/LinkDeviceLayerDialog.razor

View check run for this annotation

Codecov / codecov/patch

src/IoTHub.Portal.Client/Dialogs/Layer/LinkDeviceLayerDialog.razor#L231

Added line #L231 was not covered by tests
deviceDetails.Labels = device.Labels.ToList();
deviceDetails.LayerId = device.LayerId;

Expand Down
Loading
Loading