Skip to content

Commit

Permalink
Merge v3 Features to main branch (#1144)
Browse files Browse the repository at this point in the history
* Add target branche to CI actions

* Add PostgreSQL database to deployment (#1112)

* Add PostgreSQL database to deployment

* Add ARM lint task to v3-dev branch

* Add github actions to solution file

* Feature/add pgsql database connection (#1121)

* Add entityframework + PGSql nuget packages

* Add PGSql database context + initial database creation

* Add Quartz.NET Scheduler to server (#1135)

* Ignore migration files to code coverage

* Migrate v3-dev to v3/main branch

* Add unit of work and generic repository (#1154)

* Add unit of work and generic repository

* Add infrastructure layer + domain layer

* Move Device model property to database (#1155)

* Fix #984 - Refactor DeviceModelPropertiesController (#1159)

* Rebase from main

* Remove start Azurite from the build pipeline

* Add database servcie as adependency to iot hub portal #1175

* Fix PostgreSQL arm deployment on V3 (#1183)

* Feature: Add PostgreSQL login/password fields to arm ui form #1181

* Fix postgsql arm deployment #1180

* Update temporary arm templates urls for testing

* Update arm templates url to target main branch

* Set pgsqlAdminPassword parameter as securestring (#1188)

Co-authored-by: Hocine Hacherouf <hacherouf.hocine@gmail.com>
  • Loading branch information
kbeaugrand and hocinehacherouf authored Sep 9, 2022
1 parent b1d1971 commit 1fc869e
Show file tree
Hide file tree
Showing 131 changed files with 2,687 additions and 4,622 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/arm-ttk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Validate ARM templates

on:
pull_request:
branches: [ main ]
branches: [ main, v3-dev ]
paths:
- 'templates/**'
push:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Build & Test
# Controls when the workflow will run
on:
pull_request:
branches: [ main ]
branches: [ main, v3/main ]
push:
branches: [ main ]
branches: [ main, v3/main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand All @@ -28,11 +28,11 @@ jobs:
working-directory: src/

- name: Restore dependencies
run: dotnet restore
run: dotnet restore AzureIoTHub.Portal.sln
working-directory: src/

- name: Build
run: dotnet build --no-restore -p:ClientAssetsRestoreCommand="npm ci"
run: dotnet build AzureIoTHub.Portal.sln --no-restore -p:ClientAssetsRestoreCommand="npm ci"
working-directory: src/

- name: Generate Open API documentation
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: "Code Scanning"

on:
on:
pull_request:
branches: [ main ]
branches: [ main, v3/main ]
push:
branches: [main]
branches: [ main, v3/main ]
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
Expand Down Expand Up @@ -45,7 +45,7 @@ jobs:
queries: +security-and-quality,security-extended

- name: Build
run: dotnet build --configuration Release
run: dotnet build AzureIoTHub.Portal.sln --configuration Release
working-directory: src/

- name: Perform CodeQL Analysis
Expand Down
6 changes: 5 additions & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ coverage:
target: auto # auto compares coverage to the previous base commit
ignore:
- "**/Startup.cs"
- "**/Program.cs"
- "**/Program.cs"
- "**/PortalDbContext.cs"
- "**/Migrations/*.cs"
- "**/Seeds/*.cs"
- "**/PortalDbContextFactory.cs"
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Data.Tables" Version="12.6.1" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.6" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AzureIoTHubPortal.Domain\AzureIoTHub.Portal.Domain.csproj" />

</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
// 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.Server
namespace AzureIoTHub.Portal.Infrastructure
{
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using AzureIoTHub.Portal.Domain;

public abstract class ConfigHandler
internal abstract class ConfigHandlerBase : ConfigHandler
{
internal const string PortalNameKey = "PortalName";
internal const string IoTHubConnectionStringKey = "IoTHub:ConnectionString";
internal const string DPSConnectionStringKey = "IoTDPS:ConnectionString";
internal const string DPSServiceEndpointKey = "IoTDPS:ServiceEndpoint";
internal const string DPSIDScopeKey = "IoTDPS:IDScope";
internal const string UseSecurityHeadersKey = "UseSecurityHeaders";
internal const string PostgreSQLConnectionStringKey = "PostgreSQL:ConnectionString";

internal const string OIDCScopeKey = "OIDC:Scope";
internal const string OIDCAuthorityKey = "OIDC:Authority";
Expand Down Expand Up @@ -45,76 +43,5 @@ public abstract class ConfigHandler
internal const string IdeasUrlKey = "Ideas:Url";
internal const string IdeasAuthenticationHeaderKey = "Ideas:Authentication:Header";
internal const string IdeasAuthenticationTokenKey = "Ideas:Authentication:Token";

internal static ConfigHandler Create(IWebHostEnvironment env, IConfiguration config)
{
ArgumentNullException.ThrowIfNull(env, nameof(env));
ArgumentNullException.ThrowIfNull(config, nameof(config));

if (env.IsProduction())
{
return new ProductionConfigHandler(config);
}

return new DevelopmentConfigHandler(config);
}

internal abstract string IoTHubConnectionString { get; }

internal abstract string DPSConnectionString { get; }

internal abstract string DPSEndpoint { get; }

internal abstract string DPSScopeID { get; }

internal abstract string StorageAccountConnectionString { get; }

internal abstract int StorageAccountDeviceModelImageMaxAge { get; }

internal abstract bool UseSecurityHeaders { get; }

internal abstract string OIDCScope { get; }

internal abstract string OIDCApiClientId { get; }

internal abstract string OIDCClientId { get; }

internal abstract string OIDCMetadataUrl { get; }

internal abstract string OIDCAuthority { get; }

internal abstract bool OIDCValidateIssuer { get; }

internal abstract bool OIDCValidateAudience { get; }

internal abstract bool OIDCValidateLifetime { get; }

internal abstract bool OIDCValidateIssuerSigningKey { get; }

internal abstract bool OIDCValidateActor { get; }

internal abstract bool OIDCValidateTokenReplay { get; }

internal abstract bool IsLoRaEnabled { get; }

internal abstract string LoRaKeyManagementUrl { get; }

internal abstract string LoRaKeyManagementCode { get; }

internal abstract string LoRaKeyManagementApiVersion { get; }

internal abstract string PortalName { get; }

internal abstract int MetricExporterRefreshIntervalInSeconds { get; }

internal abstract int MetricLoaderRefreshIntervalInMinutes { get; }

internal abstract bool IdeasEnabled { get; }

internal abstract string IdeasUrl { get; }

internal abstract string IdeasAuthenticationHeader { get; }

internal abstract string IdeasAuthenticationToken { get; }
}
}
26 changes: 26 additions & 0 deletions src/AzureIoTHub.Portal.Infrastructure/ConfigHandlerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.Infrastructure
{
using System;
using AzureIoTHub.Portal.Domain;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

public static class ConfigHandlerFactory
{
public static ConfigHandler Create(IHostEnvironment env, IConfiguration config)
{
ArgumentNullException.ThrowIfNull(env, nameof(env));
ArgumentNullException.ThrowIfNull(config, nameof(config));

if (env.IsProduction())
{
return new ProductionConfigHandler(config);
}

return new DevelopmentConfigHandler(config);
}
}
}
74 changes: 74 additions & 0 deletions src/AzureIoTHub.Portal.Infrastructure/DevelopmentConfigHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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.Infrastructure
{
using Microsoft.Extensions.Configuration;

internal class DevelopmentConfigHandler : ConfigHandlerBase
{
private readonly IConfiguration config;

internal DevelopmentConfigHandler(IConfiguration config)
{
this.config = config;
}

public override string PortalName => this.config[PortalNameKey];

public override int MetricExporterRefreshIntervalInSeconds => this.config.GetValue(MetricExporterRefreshIntervalKey, 30);

public override int MetricLoaderRefreshIntervalInMinutes => this.config.GetValue(MetricLoaderRefreshIntervalKey, 10);

public override string IoTHubConnectionString => this.config[IoTHubConnectionStringKey];

public override string DPSConnectionString => this.config[DPSConnectionStringKey];

public override string DPSEndpoint => this.config[DPSServiceEndpointKey];

public override string DPSScopeID => this.config[DPSIDScopeKey];

public override string StorageAccountConnectionString => this.config[StorageAccountConnectionStringKey];

public override int StorageAccountDeviceModelImageMaxAge => this.config.GetValue(StorageAccountDeviceModelImageMaxAgeKey, 86400);

public override bool UseSecurityHeaders => this.config.GetValue(UseSecurityHeadersKey, true);

public override string OIDCScope => this.config[OIDCScopeKey];

public override string OIDCAuthority => this.config[OIDCAuthorityKey];

public override string OIDCMetadataUrl => this.config[OIDCMetadataUrlKey];

public override string OIDCClientId => this.config[OIDCClientIdKey];

public override string OIDCApiClientId => this.config[OIDCApiClientIdKey];

public override bool OIDCValidateIssuer => this.config.GetValue(OIDCValidateIssuerKey, true);

public override bool OIDCValidateAudience => this.config.GetValue(OIDCValidateAudienceKey, true);

public override bool OIDCValidateLifetime => this.config.GetValue(OIDCValidateLifetimeKey, true);

public override bool OIDCValidateIssuerSigningKey => this.config.GetValue(OIDCValidateIssuerSigningKeyKey, true);

public override bool OIDCValidateActor => this.config.GetValue(OIDCValidateActorKey, false);

public override bool OIDCValidateTokenReplay => this.config.GetValue(OIDCValidateTokenReplayKey, false);

public override bool IsLoRaEnabled => bool.Parse(this.config[IsLoRaFeatureEnabledKey] ?? "true");

public override string LoRaKeyManagementUrl => this.config[LoRaKeyManagementUrlKey];

public override string LoRaKeyManagementCode => this.config[LoRaKeyManagementCodeKey];

public override string LoRaKeyManagementApiVersion => this.config[LoRaKeyManagementApiVersionKey];

public override bool IdeasEnabled => this.config.GetValue(IdeasEnabledKey, false);
public override string IdeasUrl => this.config.GetValue(IdeasUrlKey, string.Empty);
public override string IdeasAuthenticationHeader => this.config.GetValue(IdeasAuthenticationHeaderKey, "Ocp-Apim-Subscription-Key");
public override string IdeasAuthenticationToken => this.config.GetValue(IdeasAuthenticationTokenKey, string.Empty);

public override string PostgreSQLConnectionString => this.config[PostgreSQLConnectionStringKey];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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.Infrastructure.Factories
{
using System;
using Azure;
using Azure.Data.Tables;
using AzureIoTHub.Portal.Domain;
using AzureIoTHub.Portal.Domain.Exceptions;

public class TableClientFactory : ITableClientFactory
{
private readonly string connectionString;

internal const string DeviceCommandTableName = "DeviceCommands";
internal const string DeviceTemplateTableName = "DeviceTemplates";
internal const string EdgeDeviceTemplateTableName = "EdgeDeviceTemplates";
internal const string DeviceTagSettingTableName = "DeviceTagSettings";
internal const string DeviceTemplatePropertiesTableName = "DeviceTemplateProperties";
internal const string EdgeModuleCommandsTableName = "EdgeModuleCommands";

public TableClientFactory(string connectionString)
{
this.connectionString = connectionString;
}

public TableClient GetDeviceCommands()
{
return CreateClient(DeviceCommandTableName);
}

public TableClient GetDeviceTemplates()
{
return CreateClient(DeviceTemplateTableName);
}

public TableClient GetEdgeDeviceTemplates()
{
return CreateClient(EdgeDeviceTemplateTableName);
}

public TableClient GetDeviceTagSettings()
{
return CreateClient(DeviceTagSettingTableName);
}

private TableClient CreateClient(string tableName)
{
var tableClient = new TableClient(this.connectionString, tableName);
_ = tableClient.CreateIfNotExists();

return tableClient;
}

public TableClient GetDeviceTemplateProperties()
{
return CreateClient(DeviceTemplatePropertiesTableName);
}

public TableClient GetTemplatesHealthCheck()
{
return CreateClient("tableHealthCheck");
}

public TableClient GetEdgeModuleCommands()
{
return CreateClient(EdgeModuleCommandsTableName);
}
}
}
Loading

0 comments on commit 1fc869e

Please sign in to comment.