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

Feature: Improve edge models for AWS #2142

Merged
merged 23 commits into from
Jun 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a99d894
Add edge module id to store greengrass public components
hocinehacherouf Jun 1, 2023
5be6450
Add GetPublicEdgeModules
hocinehacherouf Jun 1, 2023
c6fe3c2
Add dialogs for aws json component + public components
hocinehacherouf Jun 1, 2023
2f7875a
Update create and edit edge model pages to handle aws greengrass comp…
hocinehacherouf Jun 1, 2023
f5b7ba1
Update GetPublicEdgeModules to load all public greengrass components …
hocinehacherouf Jun 1, 2023
1d692da
Update aws greengrass dialogs
hocinehacherouf Jun 1, 2023
5a77328
Fi edge model create/edit pages to handle public and private edge mod…
hocinehacherouf Jun 1, 2023
249ad51
Remove dead code from AwsConfigService
hocinehacherouf Jun 1, 2023
1518c44
Fix class AwsConfigService after rebase
hocinehacherouf Jun 1, 2023
d501e81
Fix #2145 - Move Savechanges at last step of CRUD in edge model service
kbeaugrand Jun 1, 2023
d4004ad
Fix duplication issue after selecting public components
hocinehacherouf Jun 1, 2023
df68ce6
Fix unit tests
hocinehacherouf Jun 1, 2023
eea16fd
Fix deployment model synchronization
kbeaugrand Jun 2, 2023
9457394
Fix Edgedevice load and update
kbeaugrand Jun 2, 2023
458efbb
Add unit tests on GetPublicEdgeModules
hocinehacherouf Jun 2, 2023
6ae5671
Fix codeql warning on CreateEdgeModelShouldThrowInternalServerErrorEx…
hocinehacherouf Jun 2, 2023
159c938
Rename AwsGreengrassPublicComponents to AwsGreengrassPublicComponents…
hocinehacherouf Jun 3, 2023
696c485
Add unit tests on AwsGreengrassComponentDialog and AwsGreengrassPubli…
hocinehacherouf Jun 3, 2023
4958fb3
Add UT GetPublicEdgeModules_GetPublicEdgeModules_EdgeModulesReturned
hocinehacherouf Jun 3, 2023
9b7f91f
Add UT GetPublicEdgeModules_GetPublicEdgeModules_EdgeModulesReturned …
hocinehacherouf Jun 3, 2023
f048453
Add UT GetPublicEdgeModules_GetPublicEdgeModules_EdgeModulesReturned …
hocinehacherouf Jun 3, 2023
dc06a7e
Add unit tests on EdgeModelDetailPage and CreateEdgeModelsPage on add…
hocinehacherouf Jun 3, 2023
fe2d123
Fix codeql warning
hocinehacherouf Jun 3, 2023
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
12 changes: 7 additions & 5 deletions src/AzureIoTHub.Portal.Application/Services/IConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace AzureIoTHub.Portal.Application.Services
{
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Models.v10;
using AzureIoTHub.Portal.Shared.Models.v10;
using Microsoft.Azure.Devices;
Expand All @@ -15,13 +15,13 @@ public interface IConfigService

Task<IEnumerable<Configuration>> GetDevicesConfigurations();

Task RollOutDeviceModelConfiguration(string modelId, Dictionary<string, object> desiredProperties);
Task<string> RollOutDeviceModelConfiguration(string modelId, Dictionary<string, object> desiredProperties);

Task DeleteDeviceModelConfigurationByConfigurationNamePrefix(string configurationNamePrefix);

Task RollOutEdgeModelConfiguration(IoTEdgeModel edgeModel);
Task<string> RollOutEdgeModelConfiguration(IoTEdgeModel edgeModel);

Task RollOutDeviceConfiguration(string modelId, Dictionary<string, object> desiredProperties, string configurationId, Dictionary<string, string> targetTags, int priority = 0);
Task<string> RollOutDeviceConfiguration(string modelId, Dictionary<string, object> desiredProperties, string configurationId, Dictionary<string, string> targetTags, int priority = 0);

Task<Configuration> GetConfigItem(string id);

Expand All @@ -33,6 +33,8 @@ public interface IConfigService

Task<List<EdgeModelSystemModule>> GetModelSystemModule(string modelId);

Task<List<IoTEdgeRoute>> GetConfigRouteList(string modelId);
Task<List<IoTEdgeRoute>> GetConfigRouteList(string modelId);

Task<IEnumerable<IoTEdgeModule>> GetPublicEdgeModules();
}
}
62 changes: 31 additions & 31 deletions src/AzureIoTHub.Portal.Application/Services/IEdgeModelService.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace AzureIoTHub.Portal.Application.Services
{
using System.Collections.Generic;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Models.v10;
using AzureIoTHub.Portal.Shared.Models.v10.Filters;
using Microsoft.AspNetCore.Http;

public interface IEdgeModelService
{
Task<IEnumerable<IoTEdgeModelListItem>> GetEdgeModels(EdgeModelFilter edgeModelFilter);

Task<IoTEdgeModel> GetEdgeModel(string modelId);

Task CreateEdgeModel(IoTEdgeModel edgeModel);
Task UpdateEdgeModel(IoTEdgeModel edgeModel);

Task DeleteEdgeModel(string edgeModelId);

Task<string> GetEdgeModelAvatar(string edgeModelId);

Task<string> UpdateEdgeModelAvatar(string edgeModelId, IFormFile file);

Task DeleteEdgeModelAvatar(string edgeModelId);

Task SaveModuleCommands(IoTEdgeModel deviceModelObject);
}
}
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace AzureIoTHub.Portal.Application.Services
{
using System.Collections.Generic;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Models.v10;
using AzureIoTHub.Portal.Shared.Models.v10.Filters;
using Microsoft.AspNetCore.Http;
public interface IEdgeModelService
{
Task<IEnumerable<IoTEdgeModelListItem>> GetEdgeModels(EdgeModelFilter edgeModelFilter);
Task<IoTEdgeModel> GetEdgeModel(string modelId);
Task CreateEdgeModel(IoTEdgeModel edgeModel);
Task UpdateEdgeModel(IoTEdgeModel edgeModel);
Task DeleteEdgeModel(string edgeModelId);
Task<string> GetEdgeModelAvatar(string edgeModelId);
Task<string> UpdateEdgeModelAvatar(string edgeModelId, IFormFile file);
Task DeleteEdgeModelAvatar(string edgeModelId);
Task<IEnumerable<IoTEdgeModule>> GetPublicEdgeModules();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
@using AzureIoTHub.Portal.Models.v10;
@using System.Text.Json;

<MudDialog>
<DialogContent>
<MudForm @ref="form" @bind-IsValid="@formIsValid" >
<MudContainer Style="max-height: 600px; overflow-y: scroll">
<MudTextField id="greengrass-component-recipe-json" T="string" Label="Recipe as JSON" Variant="Variant.Text" @bind-Value="@jsonRecipe" Lines="20"
Validation="@(new Func<string, IEnumerable<string>>(ValidateJsonRecipe))" />
</MudContainer>
</MudForm>
</DialogContent>
<DialogActions>
<MudButton id="greengrass-component-cancel" OnClick="Cancel">Cancel</MudButton>
<MudButton id="greengrass-component-submit" Color="Color.Primary" OnClick="Submit" Disabled="@(!formIsValid)">Submit</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter]
MudDialogInstance MudDialog { get; set; } = default!;

[Parameter]
public IoTEdgeModule Module { get; set; } = default!;

[Parameter]
public List<IoTEdgeModule> EdgeModules { get; set; } = default!;

[Parameter]
public Context Context { get; set; } = default!;

private bool formIsValid;
private MudForm form = default!;

private string currentModuleName = default!;
private string currentModuleVersion = default!;
private string jsonRecipe = default!;

protected override void OnInitialized()
{
if (Context == Context.Edit)
{
jsonRecipe = Module.ContainerCreateOptions;
}
}

private IEnumerable<string> ValidateJsonRecipe(string json)
{
var jsonProperties = JsonSerializer.Deserialize<Dictionary<string, object>>(json) ?? new Dictionary<string, object>();

if (!jsonProperties.ContainsKey("ComponentName"))
{
currentModuleName = string.Empty;
yield return "ComponentName is missing";
}
else if (string.IsNullOrEmpty(jsonProperties["ComponentName"].ToString()))
{
currentModuleName = string.Empty;
yield return "ComponentName is empty";
}
else
{
if (Context == Context.Create && EdgeModules.Any(m => m.ModuleName.Equals(jsonProperties["ComponentName"].ToString())))
{
yield return $"Component {jsonProperties["ComponentName"].ToString()} is already used";
}
currentModuleName = jsonProperties["ComponentName"].ToString();
}

if (!jsonProperties.ContainsKey("ComponentVersion"))
{
currentModuleVersion = string.Empty;
yield return "ComponentVersion is missing";
}
else if (string.IsNullOrEmpty(jsonProperties["ComponentVersion"].ToString()))
{
currentModuleVersion = string.Empty;
yield return "ComponentVersion is empty";
}
else
{
currentModuleVersion = jsonProperties["ComponentVersion"].ToString();
}
}

void Cancel() => MudDialog.Cancel();

public async Task Submit()
{
await form.Validate();
if (!form.IsValid) return;

if(Context == Context.Create)
{
EdgeModules.Add(new IoTEdgeModule
{
ModuleName = currentModuleName,
Version = currentModuleVersion,
ImageURI = "example.com",
ContainerCreateOptions = jsonRecipe
});
}
else
{
Module.ModuleName = currentModuleName;
Module.Version = currentModuleVersion;
// ImageURI is required, but not used for Greengrass components
Module.ImageURI = "example.com";
Module.ContainerCreateOptions = jsonRecipe;
}

MudDialog.Close(DialogResult.Ok(true));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@using AzureIoTHub.Portal.Models.v10;

@inject IEdgeModelClientService EdgeModelClientService

<MudDialog>
<DialogContent>
<MudTable T="IoTEdgeModule" Items="@publicComponents" MultiSelection="true" SelectOnRowClick="true"
@bind-SelectedItems="selectedPublicComponents" Hover="true">
<HeaderContent>
<MudTh>Name</MudTh>
<MudTh>Version</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Name">@context.ModuleName</MudTd>
<MudTd DataLabel="Position">@context.Version</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[]{50, 100}" />
</PagerContent>
</MudTable>
</DialogContent>
<DialogActions>
<MudButton id="greengrass-public-components-cancel" OnClick="Cancel">Cancel</MudButton>
<MudButton id="greengrass-public-components-submit" Color="Color.Primary" OnClick="Submit">Submit</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter]
MudDialogInstance MudDialog { get; set; } = default!;

[Parameter]
public List<IoTEdgeModule> EdgeModules { get; set; } = default!;

private List<IoTEdgeModule> publicComponents = new();
private HashSet<IoTEdgeModule> selectedPublicComponents = new HashSet<IoTEdgeModule>();

protected async override Task OnInitializedAsync()
{
publicComponents = await EdgeModelClientService.GetPublicEdgeModules();
selectedPublicComponents = new HashSet<IoTEdgeModule>(publicComponents.Where(m => EdgeModules.Any(e => m.Id.Equals(e.Id))));
}

private void Cancel() => MudDialog.Cancel();

private void Submit()
{
EdgeModules.RemoveAll(e => !string.IsNullOrEmpty(e.Id));
EdgeModules.AddRange(selectedPublicComponents.ToList());

MudDialog.Close(DialogResult.Ok(true));
}

}
11 changes: 11 additions & 0 deletions src/AzureIoTHub.Portal.Client/Enums/Context.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace AzureIoTHub.Portal.Client.Enums
{
public enum Context
{
Create,
Edit
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@
Label="Device name"
Variant="Variant.Outlined"
For="@(()=> edgeDevice.DeviceName)"
Required="true" />
Required="true"
ReadOnly=@(Portal.CloudProvider == CloudProviders.AWS)/>
</MudItem>
</MudGrid>
</ChildContent>
Expand Down
Loading