From a4d333d0cbef877ffa2cc26e5c0d0f0aa796968b Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Tue, 23 Jan 2024 11:10:45 +0100 Subject: [PATCH 1/2] Fix GetInstance(IIdentity) resulting in an exception because of a wrong if clause --- .../Products/IProductManagement.cs | 2 ++ .../Facades/ProductManagementFacade.cs | 18 +++++++++++++----- .../Implementation/Storage/ProductStorage.cs | 18 ++++++++++++++++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Moryx.AbstractionLayer/Products/IProductManagement.cs b/src/Moryx.AbstractionLayer/Products/IProductManagement.cs index bfa9072fb..c5dae83ff 100644 --- a/src/Moryx.AbstractionLayer/Products/IProductManagement.cs +++ b/src/Moryx.AbstractionLayer/Products/IProductManagement.cs @@ -94,6 +94,8 @@ public interface IProductManagement : IRecipeProvider, IWorkplans /// /// Get an instance with this identity /// + /// Thrown when is null + /// Thrown when there is more than one product with the given ProductInstance GetInstance(IIdentity identity); /// diff --git a/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs b/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs index 9a12528b6..aa66686d1 100644 --- a/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs +++ b/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Copyright (c) 2024, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 using System; @@ -9,6 +9,7 @@ using Moryx.AbstractionLayer.Identity; using Moryx.AbstractionLayer.Products; using Moryx.AbstractionLayer.Recipes; +using Moryx.Logging; using Moryx.Runtime.Modules; using Moryx.Workplans; @@ -31,6 +32,8 @@ internal class ProductManagementFacade : IFacadeControl, IProductManagement public ModuleConfig Config { get; set; } + public IModuleLogger Logger { get; set; } + #endregion public void Activate() @@ -219,10 +222,15 @@ public ProductInstance GetInstance(IIdentity identity) if (identity == null) throw new ArgumentNullException(nameof(identity)); - var instance = ProductManager - .GetInstances(i => identity.Equals(i.Identity)) - .SingleOrDefault(); - return (ProductInstance) instance; + var instances = ProductManager + .GetInstances(i => identity.Equals(i.Identity)); + if (instances.Count > 1) + { + Logger.Log(LogLevel.Error, "ProductManagement contains more than one {0} with the identity {1}.", nameof(ProductInstance), identity); + throw new InvalidOperationException(); + } + + return (ProductInstance) instances.SingleOrDefault(); ; } public TInstance GetInstance(Expression> selector) diff --git a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs index 4daa21158..4d4219e78 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs @@ -17,7 +17,7 @@ using Moryx.Model.Repositories; using Moryx.Tools; using static Moryx.Products.Management.ProductExpressionHelpers; -using Moryx.Products.Management.Implementation.Storage; +using Moryx.Logging; namespace Moryx.Products.Management { @@ -71,6 +71,11 @@ internal class ProductStorage : IProductStorage, IConfiguredTypesProvider /// public ModuleConfig Config { get; set; } + /// + /// Logger for the product manager module + /// + public IModuleLogger Logger { get; set; } + /// /// Start the storage and load the type strategies /// @@ -770,6 +775,8 @@ private IReadOnlyList LoadInstancesByType(Expression false; } @@ -877,6 +884,13 @@ private void TransformInstance(IUnitOfWork uow, ProductInstanceEntity entity, Pr // Update all parts that are also present as entities foreach (var partEntity in partEntityGroups[partGroup.Key.Name]) { + if (!partGroup.Value.Any()) + { + Logger.Log(LogLevel.Warning, "No reconstruction of the property {1} possible. You have configured the {0} strategy, but the property was null." + + "Please initialize the property in the Initialize method or select the {2} strategy.", + nameof(PartSourceStrategy.FromPartlink), partGroup.Key.Name, nameof(PartSourceStrategy.FromEntities)); + continue; + } var part = partGroup.Value.First(p => p.PartLink.Id == partEntity.PartLinkEntityId); TransformInstance(uow, partEntity, part); } @@ -891,7 +905,7 @@ private void TransformInstance(IUnitOfWork uow, ProductInstanceEntity entity, Pr partArticles[index].PartLink = partLinks.Find(pl => pl?.Id == partCollection[index].PartLinkEntityId.Value); } - if (typeof(ProductInstance).IsAssignableFrom(partGroup.Key.PropertyType) && partArticles.Length == 0) + if (typeof(ProductInstance).IsAssignableFrom(partGroup.Key.PropertyType) && partArticles.Length == 1) { partGroup.Key.SetValue(productInstance, partArticles[0]); } From 91983cfc33006c88522e70a0d3f3236987392c27 Mon Sep 17 00:00:00 2001 From: Marcel Vielhaus Date: Mon, 29 Jan 2024 06:36:59 +0100 Subject: [PATCH 2/2] Port AbstractionLayer PR 221 to release 6 --- .../Facades/ProductManagementFacade.cs | 6 ++++-- .../Implementation/Storage/ProductStorage.cs | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs b/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs index aa66686d1..2acd6c0c2 100644 --- a/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs +++ b/src/Moryx.Products.Management/Facades/ProductManagementFacade.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Moryx.AbstractionLayer.Identity; using Moryx.AbstractionLayer.Products; using Moryx.AbstractionLayer.Recipes; @@ -226,8 +227,9 @@ public ProductInstance GetInstance(IIdentity identity) .GetInstances(i => identity.Equals(i.Identity)); if (instances.Count > 1) { - Logger.Log(LogLevel.Error, "ProductManagement contains more than one {0} with the identity {1}.", nameof(ProductInstance), identity); - throw new InvalidOperationException(); + var ex = new InvalidOperationException($"ProductManagement contains more than one {nameof(ProductInstance)} with the identity {identity}."); + Logger.LogError(ex, "Please make sure that an identity is unique."); + throw ex; } return (ProductInstance) instances.SingleOrDefault(); ; diff --git a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs index 4d4219e78..6cc22f922 100644 --- a/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs +++ b/src/Moryx.Products.Management/Implementation/Storage/ProductStorage.cs @@ -18,6 +18,8 @@ using Moryx.Tools; using static Moryx.Products.Management.ProductExpressionHelpers; using Moryx.Logging; +using Moryx.Products.Management.Implementation.Storage; +using Microsoft.Extensions.Logging; namespace Moryx.Products.Management { @@ -775,7 +777,7 @@ private IReadOnlyList LoadInstancesByType(Expression false; @@ -886,9 +888,9 @@ private void TransformInstance(IUnitOfWork uow, ProductInstanceEntity entity, Pr { if (!partGroup.Value.Any()) { - Logger.Log(LogLevel.Warning, "No reconstruction of the property {1} possible. You have configured the {0} strategy, but the property was null." + + Logger.LogWarning("No reconstruction of the property {1} possible. You have configured the {0} strategy, but the property was null." + "Please initialize the property in the Initialize method or select the {2} strategy.", - nameof(PartSourceStrategy.FromPartlink), partGroup.Key.Name, nameof(PartSourceStrategy.FromEntities)); + nameof(PartSourceStrategy.FromPartLink), partGroup.Key.Name, nameof(PartSourceStrategy.FromEntities)); continue; } var part = partGroup.Value.First(p => p.PartLink.Id == partEntity.PartLinkEntityId);