Skip to content

Commit

Permalink
Update to .Net 9.0 (#215)
Browse files Browse the repository at this point in the history
* Rename addressspace -> namespace

* Disable logerror warning.

* Fix using Async in method names.

* Implement disposeable on postgresql implementation.

* bug fix.

* Bug and code analyzer warning fixes and fix naming of cloudlibclient variables.

* Fix regression.

* Fix regression.

* Fix formatting.

* fix formatting.

* fix formatting.

* fix formatting.

* Fix formatting.

* Added docker compose back into solution file and deleted extra solution file.

* Fix one more (misspelt) addressspace -> namespace rename.

* Remove dups from category and org queries.

* Remove unneeded using.

* Fix cut and paste error.

* Fix client lib.

* Property name change from nodesetCreationTime to publicationDate to be consistent.

* Fix for bug #90

* Fixes security CVE-2022-30187 and maintain stack info on exception.

* Fix build break and CVEs.

* Added Azure Data Protection Key per instance and updated NuGets.

* Fix version string.

* Fix CloudLib Explorer exception and many async and dependency injection-related issues.

* update version to match spec.

* Fix usings/whitespace.

* Move QueryModel to GraphQL folder.

* Switch to Postmark as Sendgrid disabled our account and was unreliable anyway.

* Bring sendgrid back in optionally.

* Added description for data protection env variable.

* Fix CVE and update other NuGets, too.

* Switch to localhost for DB endpoint and add missing env variable.

* Re-enabling builsing the sync tool.

* NodeSetModel 1.0.13 plus migrations

* File encoding fix

* Update to latest OPC UA stack to avoid security issue.

* 1. Add OAuth2 auth via OPC Foundation website and additional login UI from ASP.NetCore Identity Scafolding.
2. Add missing ConfigureAwaits.
3. Simplify auth in Swagger.
4. Add account management UI from ASP.NetCore Identity Scafolding.
5. Add email confirmation management from ASP.NetCore Identity Scafolding.

* Remove unnecessary usings.

* Test: add oauth2 config

* Bug fix.

* Added unsubscribe link to verification emails and small code cleanup.

* Add more context to system emails.

* Remove URLs encode.

* Code cleanup and make verification email a little prettier.

* remove redundant file.

* Remove resend email confirmation feature.

* Update to latest NuGets.

* Upgraded to .Net9.0/.NetStandard2.1, updated all NuGets, fixed all error due to depricated APIs and fixed all warnings (use specific types instead of var, usings consistently declared outside of namespaces, inline arrays declared as class members, class naming conventions, marking internal classes as sealed where possible, don't use .Any() for perf)

* Removed GraphQL Playground as it is no longer maintained.

* Update to .Net9.0

* Bug Fix.

* Fix for breaking change in .Net9.0: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-9.0/breaking-changes#pending-model-changes

* Also return version and publication date from /infomodel/namespaces API

* Add retry to startup for database connectivity.

* Code formatting fixes.

---------

Co-authored-by: Markus Horstmann <[email protected]>
Co-authored-by: Randy Armstrong <[email protected]>
  • Loading branch information
3 people authored Jan 8, 2025
1 parent aea7ed1 commit 0a533bd
Show file tree
Hide file tree
Showing 112 changed files with 1,307 additions and 1,351 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ jobs:
steps:
- name: 🤘 checkout
uses: actions/checkout@v2
with:
with:
submodules: recursive
fetch-depth: 0
- name: ⚙ dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
dotnet-version: '9.0.x'
- name: Workaround
#https://github.com/dotnet/format/issues/1433#issuecomment-1055920818
run: dotnet tool install -g dotnet-format --version "6.*" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json
run: dotnet tool install -g dotnet-format --version "9.*" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json
- name: ✓ ensure format UA-CloudLibrary Server
working-directory: UACloudLibraryServer
run: dotnet-format --verify-no-changes -v:diag --exclude ~/.nuget
Expand All @@ -48,15 +48,15 @@ jobs:
- name: List existing databases
run: |
sudo -u postgres psql -l --command="\du"
- name: 🤘 checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: ⚙ dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
dotnet-version: '9.0.x'
- name: Restore dependencies UA-CloudLibrary
working-directory: UACloudLibraryServer
run: dotnet restore
Expand Down
48 changes: 24 additions & 24 deletions CloudLibSync/CloudLibSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ public async Task DownloadAsync(string sourceUrl, string sourceUserName, string
// Get all NodeSets
nodeSetResult = await sourceClient.GetNodeSetsAsync(after: cursor, first: 50).ConfigureAwait(false);

foreach (var nodeSetAndCursor in nodeSetResult.Edges)
foreach (GraphQlNodeAndCursor<Nodeset>? nodeSetAndCursor in nodeSetResult.Edges)
{
// Download each NodeSet
var identifier = nodeSetAndCursor.Node.Identifier.ToString(CultureInfo.InvariantCulture);
var uaNamespace = await sourceClient.DownloadNodesetAsync(identifier).ConfigureAwait(false);
string identifier = nodeSetAndCursor.Node.Identifier.ToString(CultureInfo.InvariantCulture);
UANameSpace uaNamespace = await sourceClient.DownloadNodesetAsync(identifier).ConfigureAwait(false);

if (uaNamespace?.Nodeset != null)
{
Expand All @@ -55,9 +55,9 @@ public async Task DownloadAsync(string sourceUrl, string sourceUserName, string
}


var original = JsonConvert.SerializeObject(uaNamespace, Formatting.Indented);
var namespaceKey = VerifyAndFixupNodeSetMeta(uaNamespace);
var fileName = GetFileNameForNamespaceUri(namespaceKey.ModelUri, namespaceKey.PublicationDate);
string original = JsonConvert.SerializeObject(uaNamespace, Formatting.Indented);
(string? ModelUri, DateTime? PublicationDate, bool Changed) namespaceKey = VerifyAndFixupNodeSetMeta(uaNamespace);
string fileName = GetFileNameForNamespaceUri(namespaceKey.ModelUri, namespaceKey.PublicationDate);

File.WriteAllText(Path.Combine(localDir, $"{fileName}.{identifier}.json"), JsonConvert.SerializeObject(uaNamespace, Formatting.Indented));

Expand Down Expand Up @@ -133,17 +133,17 @@ public async Task SynchronizeAsync(string sourceUrl, string sourceUserName, stri
source.NamespaceUri?.OriginalString== target.NamespaceUri?.OriginalString
&& (source.PublicationDate == target.PublicationDate || (source.Identifier != 0 && source.Identifier == target.Identifier))
)).ToList();
foreach (var nodeSet in toSync)
foreach (Nodeset? nodeSet in toSync)
{
// Download each NodeSet
var identifier = nodeSet.Identifier.ToString(CultureInfo.InvariantCulture);
var uaNamespace = await sourceClient.DownloadNodesetAsync(identifier).ConfigureAwait(false);
string identifier = nodeSet.Identifier.ToString(CultureInfo.InvariantCulture);
UANameSpace uaNamespace = await sourceClient.DownloadNodesetAsync(identifier).ConfigureAwait(false);

try
{
VerifyAndFixupNodeSetMeta(uaNamespace);
// upload NodeSet to target cloud library
var response = await targetClient.UploadNodeSetAsync(uaNamespace).ConfigureAwait(false);
(System.Net.HttpStatusCode Status, string Message) response = await targetClient.UploadNodeSetAsync(uaNamespace).ConfigureAwait(false);
if (response.Status == System.Net.HttpStatusCode.OK)
{
bAdded = true;
Expand Down Expand Up @@ -187,22 +187,22 @@ public async Task UploadAsync(string targetUrl, string targetUserName, string ta
filesToUpload.AddRange(Directory.GetFiles(localDir));
}

foreach (var file in filesToUpload)
foreach (string file in filesToUpload)
{
var uploadJson = File.ReadAllText(file);
string uploadJson = File.ReadAllText(file);

var addressSpace = JsonConvert.DeserializeObject<UANameSpace>(uploadJson);
UANameSpace? addressSpace = JsonConvert.DeserializeObject<UANameSpace>(uploadJson);
if (addressSpace == null)
{
_logger.LogInformation($"Error uploading {file}: failed to parse.");
continue;
}
if (addressSpace.Nodeset == null || string.IsNullOrEmpty(addressSpace.Nodeset.NodesetXml))
{
var xmlFile = Path.Combine(Path.GetDirectoryName(file)??file, Path.GetFileNameWithoutExtension(file) + ".xml");
string xmlFile = Path.Combine(Path.GetDirectoryName(file)??file, Path.GetFileNameWithoutExtension(file) + ".xml");
if (File.Exists(xmlFile))
{
var xml = File.ReadAllText(xmlFile);
string xml = File.ReadAllText(xmlFile);
addressSpace.Nodeset = new Nodeset { NodesetXml = xml };
}
}
Expand Down Expand Up @@ -235,7 +235,7 @@ public async Task UploadAsync(string targetUrl, string targetUserName, string ta
{
addressSpace.Contributor = new Organisation { Name = file };
}
var response = await targetClient.UploadNodeSetAsync(addressSpace).ConfigureAwait(false);
(System.Net.HttpStatusCode Status, string Message) response = await targetClient.UploadNodeSetAsync(addressSpace).ConfigureAwait(false);
if (response.Status == System.Net.HttpStatusCode.OK)
{
_logger.LogInformation($"Uploaded {addressSpace.Nodeset.NamespaceUri}, {addressSpace.Nodeset.Identifier}");
Expand All @@ -250,16 +250,16 @@ public async Task UploadAsync(string targetUrl, string targetUserName, string ta
private (string? ModelUri, DateTime? PublicationDate, bool Changed) VerifyAndFixupNodeSetMeta(UANameSpace uaNamespace)
{
bool changed = false;
var nodeset = uaNamespace.Nodeset;
var namespaceUri = nodeset?.NamespaceUri?.OriginalString;
var publicationDate = nodeset?.PublicationDate;
Nodeset? nodeset = uaNamespace.Nodeset;
string? namespaceUri = nodeset?.NamespaceUri?.OriginalString;
DateTime? publicationDate = nodeset?.PublicationDate;

if (nodeset?.NodesetXml != null)
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(nodeset.NodesetXml)))
{
var nodeSet = UANodeSet.Read(ms);
var firstModel = nodeSet.Models?.FirstOrDefault();
ModelTableEntry? firstModel = nodeSet.Models?.FirstOrDefault();
if (firstModel != null)
{
if (firstModel.PublicationDateSpecified && firstModel.PublicationDate != DateTime.MinValue && firstModel.PublicationDate != nodeset.PublicationDate)
Expand Down Expand Up @@ -324,10 +324,10 @@ public async Task UploadAsync(string targetUrl, string targetUserName, string ta

private static string GetFileNameForNamespaceUri(string? modelUri, DateTime? publicationDate)
{
var tFile = modelUri?.Replace("http://", "", StringComparison.OrdinalIgnoreCase) ?? "";
string tFile = modelUri?.Replace("http://", "", StringComparison.OrdinalIgnoreCase) ?? "";
tFile = tFile.Replace('/', '.');
tFile = tFile.Replace(':', '_');
if (!tFile.EndsWith(".", StringComparison.Ordinal)) tFile += ".";
if (!tFile.EndsWith('.')) tFile += ".";
if (publicationDate != null && publicationDate.Value != default)
{
if (publicationDate.Value.TimeOfDay == TimeSpan.Zero)
Expand All @@ -345,8 +345,8 @@ private static string GetFileNameForNamespaceUri(string? modelUri, DateTime? pub

static void SaveNodeSetAsXmlFile(UANameSpace? nameSpace, string directoryPath)
{
var modelUri = nameSpace?.Nodeset?.NamespaceUri?.OriginalString;
var publicationDate = nameSpace?.Nodeset?.PublicationDate;
string? modelUri = nameSpace?.Nodeset?.NamespaceUri?.OriginalString;
DateTime? publicationDate = nameSpace?.Nodeset?.PublicationDate;
if ((modelUri == null || publicationDate == null) && nameSpace?.Nodeset != null)
{
var ms = new MemoryStream(Encoding.UTF8.GetBytes(nameSpace.Nodeset.NodesetXml));
Expand Down
8 changes: 4 additions & 4 deletions CloudLibSync/CloudLibSync.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Opc.Ua.CloudLib.Client\Opc.Ua.Cloud.Library.Client.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Core" Version="1.5.374.118" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Core" Version="1.5.374.158" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta3.22114.1" />
<PackageReference Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta3.22114.1" />
</ItemGroup>
Expand All @@ -20,7 +20,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.6.143" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.6.146" />
</ItemGroup>

</Project>
3 changes: 2 additions & 1 deletion CloudLibSync/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
using Microsoft.Extensions.Logging;
using Opc.Ua.CloudLib.Sync;

class Program : ILogger
[assembly: CLSCompliant(false)]
sealed class Program : ILogger
{
public static Task<int> Main(string[] args)
{
Expand Down
8 changes: 4 additions & 4 deletions CloudLibSyncAzureFunction/CloudLibSyncAzureFunction.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.1" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CloudLibSync\CloudLibSync.csproj" />
Expand All @@ -25,6 +25,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.6.143" />
<PackageReference Update="Nerdbank.GitVersioning" Version="3.6.146" />
</ItemGroup>
</Project>
11 changes: 7 additions & 4 deletions CloudLibSyncAzureFunction/CloudSyncFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
using Opc.Ua.CloudLib.Sync;

[assembly: FunctionsStartup(typeof(CloudLibSyncAzureFunction.CloudSyncFunctionStartup))]

[assembly: CLSCompliant(false)]
namespace CloudLibSyncAzureFunction
{

Expand Down Expand Up @@ -39,15 +39,18 @@ public CloudSyncFunction(IOptions<CloudLibSyncOptions> options)
{
if (options == null || options.Value == null)
{
throw new ArgumentNullException(nameof(CloudLibSyncOptions));
string error = nameof(CloudLibSyncOptions);
throw new ArgumentNullException(error);
}
if (options.Value.Source == null)
{
throw new ArgumentNullException(nameof(options.Value.Source));
string error = nameof(options.Value.Source);
throw new ArgumentNullException(error);
}
if (options.Value.Target == null)
{
throw new ArgumentNullException(nameof(options.Value.Target));
string error = nameof(options.Value.Target);
throw new ArgumentNullException(error);
}
_options = options.Value;
}
Expand Down
8 changes: 4 additions & 4 deletions Opc.Ua.CloudLib.Client/GraphQlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using System;
using System.Linq.Expressions;
using GraphQL.Query.Builder;

namespace Opc.Ua.Cloud.Library.Client
{
using System;
using System.Linq.Expressions;
using GraphQL.Query.Builder;

static class GraphQlExtensions
{
public static IQuery<TSource> AddFields<TSource>(this IQuery<TSource> This, Func<IQuery<TSource>, IQuery<TSource>> addFields, bool skip = false)
Expand Down
27 changes: 15 additions & 12 deletions Opc.Ua.CloudLib.Client/MetadataConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using global::Opc.Ua.Cloud.Library.Client.Models;

namespace Opc.Ua.Cloud.Library.Client
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using global::Opc.Ua.Cloud.Library.Client.Models;

static class MetadataConverter
{
/// <summary>
Expand All @@ -49,14 +49,15 @@ public static List<UANameSpace> Convert(List<MetadataResult> metadata)
foreach (MetadataResult item in metadata)
{
string id = item.NodesetID.ToString(CultureInfo.InvariantCulture);
if (!nameSpaces.ContainsKey(id))
if (!nameSpaces.TryGetValue(id, out UANameSpace value))
{
var uaNamespace = new UANameSpace();
uaNamespace.Nodeset.Identifier = (uint)item.NodesetID;
nameSpaces.Add(id, uaNamespace);
value = uaNamespace;
nameSpaces.Add(id, value);
}

ConvertCases(nameSpaces[id], item);
ConvertCases(value, item);
}
}

Expand Down Expand Up @@ -146,6 +147,8 @@ public static List<UANameSpace> ConvertWithPaging(List<UANodesetResult> infos, i
return result;
}

internal static readonly char[] separator = new char[] { ',' };

/// <summary>
/// Switch case with all the names for the members
/// </summary>
Expand Down Expand Up @@ -173,10 +176,10 @@ private static void ConvertCases(UANameSpace nameSpace, MetadataResult metadata)
nameSpace.PurchasingInformationUrl = new Uri(metadata.Value);
break;
case "keywords":
nameSpace.Keywords = metadata.Value.Split(new char[] { ',' });
nameSpace.Keywords = metadata.Value.Split(separator);
break;
case "locales":
nameSpace.SupportedLocales = metadata.Value.Split(new char[] { ',' });
nameSpace.SupportedLocales = metadata.Value.Split(separator);
break;
case "numdownloads":
nameSpace.NumberOfDownloads = System.Convert.ToUInt32(metadata.Value, CultureInfo.InvariantCulture);
Expand Down Expand Up @@ -237,7 +240,7 @@ private static void ConvertCases(UANameSpace nameSpace, MetadataResult metadata)
#endregion
default:
{
var additionalProps = nameSpace.AdditionalProperties?.ToList() ?? new List<UAProperty>();
List<UAProperty> additionalProps = nameSpace.AdditionalProperties?.ToList() ?? new List<UAProperty>();
additionalProps.Add(new UAProperty { Name = metadata.Name, Value = metadata.Value });
nameSpace.AdditionalProperties = additionalProps.ToArray();
break;
Expand Down
4 changes: 2 additions & 2 deletions Opc.Ua.CloudLib.Client/Models/DataResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using Newtonsoft.Json;

namespace Opc.Ua.Cloud.Library.Client.Models
{
using Newtonsoft.Json;

/// <summary>GraphQL Result for datatype queries</summary>
[JsonObject("dataType")]
public class DataResult
Expand Down
11 changes: 5 additions & 6 deletions Opc.Ua.CloudLib.Client/Models/GraphQLNodeSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace Opc.Ua.Cloud.Library.Client
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;


/// <summary>
/// GraphQL version of the class
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions Opc.Ua.CloudLib.Client/Models/MetadataResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/

using Newtonsoft.Json;

namespace Opc.Ua.Cloud.Library.Client.Models
{
using Newtonsoft.Json;

/// <summary>GraphQL Result for metadata queries</summary>
[JsonObject("metadata")]
public class MetadataResult
Expand Down
Loading

0 comments on commit 0a533bd

Please sign in to comment.