diff --git a/COMET.Web.Common.Tests/Extensions/SessionServiceExtensionsTestFixture.cs b/COMET.Web.Common.Tests/Extensions/SessionServiceExtensionsTestFixture.cs
new file mode 100644
index 00000000..c946fbec
--- /dev/null
+++ b/COMET.Web.Common.Tests/Extensions/SessionServiceExtensionsTestFixture.cs
@@ -0,0 +1,91 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) 2023 RHEA System S.A.
+//
+// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine
+//
+// This file is part of COMET WEB Community Edition
+// The COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C.
+//
+// The COMET WEB Community Edition is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Affero General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// The COMET WEB Community Edition is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace COMET.Web.Common.Tests.Extensions
+{
+ using CDP4Common.EngineeringModelData;
+ using CDP4Common.SiteDirectoryData;
+
+ using CDP4Dal;
+ using CDP4Dal.Operations;
+
+ using COMET.Web.Common.Extensions;
+ using COMET.Web.Common.Services.SessionManagement;
+ using Microsoft.Extensions.Logging;
+ using Moq;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class SessionServiceExtensionsTestFixture
+ {
+ private Mock session;
+ private ISessionService sessionService;
+
+ [SetUp]
+ public void Setup()
+ {
+ var logger = new Mock>();
+
+ this.session = new Mock();
+ this.sessionService = new SessionService(logger.Object)
+ {
+ Session = this.session.Object
+ };
+ }
+
+ [Test]
+ public void VerifyAddParameter()
+ {
+ var model = new EngineeringModel();
+ var iterationSetup = new IterationSetup();
+ var iteration = new Iteration()
+ {
+ IterationSetup = iterationSetup,
+ Container = model
+ };
+ model.Iteration.Add(iteration);
+
+ var elementDefinition = new ElementDefinition();
+ iteration.Element.Add(elementDefinition);
+
+ var textParameterType = new TextParameterType();
+
+ var doe = new DomainOfExpertise()
+ {
+ Name = "doe",
+ ShortName = "doe"
+ };
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(() => this.sessionService.AddParameter(null, null, null, null, null), Throws.ArgumentNullException);
+ Assert.That(() => this.sessionService.AddParameter(elementDefinition, null, null, null, null), Throws.ArgumentNullException);
+ Assert.That(() => this.sessionService.AddParameter(elementDefinition, null, textParameterType, null, null), Throws.ArgumentNullException);
+ Assert.That(() => this.sessionService.AddParameter(elementDefinition, null, textParameterType, null, doe), Throws.Nothing);
+ });
+
+ this.session.Verify(x => x.Write(It.IsAny()), Times.Once);
+ }
+ }
+}
diff --git a/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs b/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
index 5820d5f1..6c54ff78 100644
--- a/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
+++ b/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
@@ -36,6 +36,9 @@ namespace COMET.Web.Common.Tests.Services.SessionManagement
using COMET.Web.Common.Enumerations;
using COMET.Web.Common.Services.SessionManagement;
+
+ using Microsoft.Extensions.Logging;
+
using Moq;
using NUnit.Framework;
@@ -59,8 +62,13 @@ public class SessionServiceTestFixture
[SetUp]
public void Setup()
{
+ var logger = new Mock>();
+
this.session = new Mock();
- this.sessionService = new SessionService { Session = this.session.Object };
+ this.sessionService = new SessionService(logger.Object)
+ {
+ Session = this.session.Object
+ };
this.assembler = new Assembler(this.uri);
this.domain = new DomainOfExpertise(Guid.NewGuid(), this.assembler.Cache, this.uri);
diff --git a/COMET.Web.Common/COMET.Web.Common.csproj b/COMET.Web.Common/COMET.Web.Common.csproj
index d812aeb2..a254f0e7 100644
--- a/COMET.Web.Common/COMET.Web.Common.csproj
+++ b/COMET.Web.Common/COMET.Web.Common.csproj
@@ -3,7 +3,7 @@
net7.0
Latest
- 1.0.39
+ 1.0.40
1.0.0
1.0.0
CDP4 WEB Common
@@ -27,6 +27,7 @@
+
diff --git a/COMET.Web.Common/Extensions/SessionServiceExtensions.cs b/COMET.Web.Common/Extensions/SessionServiceExtensions.cs
new file mode 100644
index 00000000..821d0f4c
--- /dev/null
+++ b/COMET.Web.Common/Extensions/SessionServiceExtensions.cs
@@ -0,0 +1,87 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) 2023 RHEA System S.A.
+//
+// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine
+//
+// This file is part of COMET WEB Community Edition
+// The COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C.
+//
+// The COMET WEB Community Edition is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Affero General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// The COMET WEB Community Edition is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace COMET.Web.Common.Extensions
+{
+ using CDP4Common.EngineeringModelData;
+ using CDP4Common.SiteDirectoryData;
+
+ using COMET.Web.Common.Services.SessionManagement;
+
+ using FluentResults;
+
+ ///
+ /// Static class with extension methods for the
+ ///
+ public static class SessionServiceExtensions
+ {
+ ///
+ /// Adds a new parameter for a given element definition
+ ///
+ /// The in which data will be updated
+ /// The in which a new parameter will be added
+ /// The of the new parameter
+ /// The of the new parameter
+ /// The of the new parameter
+ /// The of the owner
+ /// A
+ /// Throws an
+ public static async Task AddParameter(this ISessionService sessionService, ElementDefinition elementDefinition, ParameterGroup group, ParameterType parameterType, MeasurementScale measurementScale, DomainOfExpertise owner)
+ {
+ if (elementDefinition == null)
+ {
+ throw new ArgumentNullException(nameof(elementDefinition), "The container ElementDefinition may not be null");
+ }
+
+ if (parameterType == null)
+ {
+ throw new ArgumentNullException(nameof(parameterType), "The ParameterType may not be null");
+ }
+
+ if (owner == null)
+ {
+ throw new ArgumentNullException(nameof(owner), "The owner DomainOfExpertise may not be null");
+ }
+
+ if (sessionService.Session == null)
+ {
+ throw new ArgumentNullException(nameof(sessionService.Session), "The session may not be null");
+ }
+
+ var parameter = new Parameter(Guid.NewGuid(), null, null)
+ {
+ Owner = owner,
+ ParameterType = parameterType,
+ Scale = measurementScale,
+ Group = group,
+ ValueSet = { new ParameterValueSet() }
+ };
+
+ var clone = elementDefinition.Clone(false);
+ clone.Parameter.Add(parameter);
+
+ return await sessionService.CreateThing(clone, parameter);
+ }
+ }
+}
diff --git a/COMET.Web.Common/Services/SessionManagement/ISessionService.cs b/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
index 68e4a680..2875261e 100644
--- a/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
+++ b/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
@@ -33,6 +33,8 @@ namespace COMET.Web.Common.Services.SessionManagement
using DynamicData;
+ using FluentResults;
+
///
/// The interface provides access to an
///
@@ -75,8 +77,8 @@ public interface ISessionService
///
/// The selected
/// The
- /// An asynchronous operation
- Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise domain);
+ /// An asynchronous operation with a
+ Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise domain);
///
/// Close all the opened
@@ -125,72 +127,72 @@ public interface ISessionService
///
/// the container where the should be created
/// the thing to create in the session
- /// An asynchronous operation
- Task CreateThing(Thing container, Thing thingToCreate);
+ /// An asynchronous operation with a
+ Task CreateThing(Thing container, Thing thingToCreate);
///
/// Write new Things in an
///
/// the container where the should be created
/// the things to create in the session
- /// An asynchronous operation
- Task CreateThings(Thing container, params Thing[] thingsToCreate);
+ /// An asynchronous operation with a
+ Task CreateThings(Thing container, params Thing[] thingsToCreate);
///
/// Write new Things in an
///
/// The where the s should be created
/// List of Things to create in the session
- /// An asynchronous operation
- Task CreateThings(Thing container, IEnumerable thingsToCreate);
+ /// An asynchronous operation with a
+ Task CreateThings(Thing container, IEnumerable thingsToCreate);
///
/// Write updated Thing in an
///
/// The where the s should be updated
/// the thing to update in the session
- /// An asynchronous operation
- Task UpdateThing(Thing container, Thing thingToUpdate);
+ /// An asynchronous operation with a
+ Task UpdateThing(Thing container, Thing thingToUpdate);
///
/// Write updated Things in an
///
/// The where the s should be updated
/// List of Things to update in the session
- /// An asynchronous operation
- Task UpdateThings(Thing container, params Thing[] thingsToUpdate);
+ /// An asynchronous operation with a
+ Task UpdateThings(Thing container, params Thing[] thingsToUpdate);
///
/// Write updated Things in an
///
/// The where the s should be updated
/// List of Things to update in the session
- /// An asynchronous operation
- Task UpdateThings(Thing container, IEnumerable thingsToUpdate);
+ /// An asynchronous operation with a
+ Task UpdateThings(Thing container, IEnumerable thingsToUpdate);
///
/// Deletes a from it's container
///
/// the container clone of the thing to delete
/// the thing to delete in the session
- /// An asynchronous operation
- Task DeleteThing(Thing containerClone, Thing thingToDelete);
+ /// An asynchronous operation with a
+ Task DeleteThing(Thing containerClone, Thing thingToDelete);
///
/// Deletes a collection of from it's container
///
/// the container clone of the thing to delete
/// the things to delete in the session
- /// An asynchronous operation
- Task DeleteThings(Thing containerClone, params Thing[] thingsToDelete);
+ /// An asynchronous operation with a
+ Task DeleteThings(Thing containerClone, params Thing[] thingsToDelete);
///
/// Deletes a collection from it's container
///
/// the container clone of the thing to delete
/// the things to delete in the session
- /// An asynchronous operation
- Task DeleteThings(Thing containerClone, IEnumerable thingsToDelete);
+ /// An asynchronous operation with a
+ Task DeleteThings(Thing containerClone, IEnumerable thingsToDelete);
///
/// Gets the inside an iteration
diff --git a/COMET.Web.Common/Services/SessionManagement/SessionService.cs b/COMET.Web.Common/Services/SessionManagement/SessionService.cs
index 3a18ff1c..d792332a 100644
--- a/COMET.Web.Common/Services/SessionManagement/SessionService.cs
+++ b/COMET.Web.Common/Services/SessionManagement/SessionService.cs
@@ -39,7 +39,9 @@ namespace COMET.Web.Common.Services.SessionManagement
using DynamicData;
- using NLog;
+ using FluentResults;
+
+ using Microsoft.Extensions.Logging;
using ReactiveUI;
@@ -50,9 +52,9 @@ namespace COMET.Web.Common.Services.SessionManagement
public class SessionService : ReactiveObject, ISessionService
{
///
- /// The current class
+ /// The
///
- private readonly Logger logger = LogManager.GetCurrentClassLogger();
+ private readonly ILogger logger;
///
/// Gets a readonly collection of open
@@ -74,6 +76,15 @@ public class SessionService : ReactiveObject, ISessionService
///
public bool IsSessionOpen { get; set; }
+ ///
+ /// Creates a new instance of type
+ ///
+ /// the
+ public SessionService(ILogger logger)
+ {
+ this.logger = logger;
+ }
+
///
/// Retrieves the that is loaded in the
///
@@ -104,8 +115,12 @@ public async Task Close()
///
/// The selected
/// The
- public async Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise domain)
+ /// An asynchronous operation with a
+ public async Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise domain)
{
+ var result = new Result();
+
+ this.logger.LogInformation("Opening iteration");
var modelSetup = (EngineeringModelSetup)iterationSetup.Container;
var model = new EngineeringModel(modelSetup.EngineeringModelIid, this.Session.Assembler.Cache, this.Session.Credentials.Uri);
@@ -127,12 +142,17 @@ public async Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise
this.OpenIterations.Add(openedIteration);
CDPMessageBus.Current.SendMessage(SessionStateKind.IterationOpened);
+ this.logger.LogInformation("Iteration opened successfully");
+ result.Successes.Add(new Success("Iteration opened successfully"));
}
catch (Exception exception)
{
- this.logger.Error($"During read operation an error has occured: {exception.Message}");
+ this.logger.LogError($"During read operation an error has occured: {exception.Message}", exception);
+ result.Errors.Add(new Error($"During read operation an error has occured: {exception.Message}"));
throw;
}
+
+ return result;
}
///
@@ -140,6 +160,8 @@ public async Task ReadIteration(IterationSetup iterationSetup, DomainOfExpertise
///
public void CloseIterations()
{
+ this.logger.LogInformation("Closing all the opened iterations");
+
foreach (var iteration in this.OpenIterations.Items.ToList())
{
this.CloseIteration(iteration);
@@ -152,6 +174,7 @@ public void CloseIterations()
/// The
public void CloseIteration(Iteration iteration)
{
+ this.logger.LogInformation($"Closing iteration with id {iteration.Iid}");
this.Session.CloseIterationSetup(iteration.IterationSetup);
this.OpenIterations.Remove(this.OpenIterations.Items.First(x => x.Iid == iteration.Iid));
}
@@ -202,7 +225,7 @@ public async Task RefreshSession()
CDPMessageBus.Current.SendMessage(SessionStateKind.RefreshEnded);
- Console.WriteLine($"Session refreshed in {sw.ElapsedMilliseconds} [ms]");
+ this.logger.LogInformation($"Session refreshed in {sw.ElapsedMilliseconds} [ms]");
}
///
@@ -220,10 +243,10 @@ public void SwitchDomain(Iteration iteration, DomainOfExpertise domainOfExpertis
///
/// the container where the should be created
/// the thing to create in the session
- /// An asynchronous operation
- public async Task CreateThing(Thing container, Thing thingToCreate)
+ /// An asynchronous operation with a
+ public async Task CreateThing(Thing container, Thing thingToCreate)
{
- await this.CreateThings(container, new List { thingToCreate });
+ return await this.CreateThings(container, new List { thingToCreate });
}
///
@@ -231,10 +254,10 @@ public async Task CreateThing(Thing container, Thing thingToCreate)
///
/// the container where the should be created
/// the things to create in the session
- /// An asynchronous operation
- public async Task CreateThings(Thing container, params Thing[] thingsToCreate)
+ /// An asynchronous operation with a
+ public async Task CreateThings(Thing container, params Thing[] thingsToCreate)
{
- await this.CreateThings(container, thingsToCreate.ToList());
+ return await this.CreateThings(container, thingsToCreate.ToList());
}
///
@@ -242,11 +265,15 @@ public async Task CreateThings(Thing container, params Thing[] thingsToCreate)
///
/// The where the s should be created
/// List of Things to create in the session
- public async Task CreateThings(Thing thing, IEnumerable thingsToCreate)
+ /// An asynchronous operation with a
+ public async Task CreateThings(Thing thing, IEnumerable thingsToCreate)
{
+ var result = new Result();
+
if (thingsToCreate == null)
{
- return;
+ result.Errors.Add(new Error("The things to create can't be null"));
+ return result;
}
var thingClone = thing;
@@ -270,12 +297,16 @@ public async Task CreateThings(Thing thing, IEnumerable thingsToCreate)
try
{
await this.Session.Write(operationContainer);
- Console.WriteLine("Writing done !");
+ this.logger.LogInformation("Writing done!");
+ result.Successes.Add(new Success("Writing done!"));
}
catch (DalWriteException ex)
{
- Console.WriteLine($"The create operation failed: {ex.Message}");
+ this.logger.LogError($"The create operation failed: {ex.Message}", ex);
+ result.Errors.Add(new Error($"The create operation failed: {ex.Message}"));
}
+
+ return result;
}
///
@@ -283,10 +314,10 @@ public async Task CreateThings(Thing thing, IEnumerable thingsToCreate)
///
/// The where the s should be updated
/// the thing to update in the session
- /// An asynchronous operation
- public async Task UpdateThing(Thing container, Thing thingToUpdate)
+ /// An asynchronous operation with a
+ public async Task UpdateThing(Thing container, Thing thingToUpdate)
{
- await this.UpdateThings(container, new List { thingToUpdate });
+ return await this.UpdateThings(container, new List { thingToUpdate });
}
///
@@ -294,10 +325,10 @@ public async Task UpdateThing(Thing container, Thing thingToUpdate)
///
/// The where the s should be updated
/// List of Things to update in the session
- /// An asynchronous operation
- public async Task UpdateThings(Thing container, params Thing[] thingsToUpdate)
+ /// An asynchronous operation with a
+ public async Task UpdateThings(Thing container, params Thing[] thingsToUpdate)
{
- await this.UpdateThings(container, thingsToUpdate.ToList());
+ return await this.UpdateThings(container, thingsToUpdate.ToList());
}
///
@@ -305,11 +336,15 @@ public async Task UpdateThings(Thing container, params Thing[] thingsToUpdate)
///
/// The where the s should be updated
/// List of Things to update in the session
- public async Task UpdateThings(Thing thing, IEnumerable thingsToUpdate)
+ /// An asynchronous operation with a
+ public async Task UpdateThings(Thing thing, IEnumerable thingsToUpdate)
{
+ var result = new Result();
+
if (thingsToUpdate == null)
{
- return;
+ result.Errors.Add(new Error("The things to update can't be null"));
+ return result;
}
var sw = Stopwatch.StartNew();
@@ -336,16 +371,20 @@ public async Task UpdateThings(Thing thing, IEnumerable thingsToUpdate)
try
{
await this.Session.Write(operationContainer);
- Console.WriteLine($"Update writing done in {sw.ElapsedMilliseconds} [ms]");
+ this.logger.LogInformation($"Update writing done in {sw.ElapsedMilliseconds} [ms]");
+ result.Successes.Add(new Success($"Update writing done in {sw.ElapsedMilliseconds} [ms]"));
}
catch (Exception ex)
{
- Console.WriteLine($"The update operation failed: {ex.Message}");
+ this.logger.LogError($"The update operation failed: {ex.Message}", ex);
+ result.Errors.Add(new Error($"The update operation failed: {ex.Message}"));
}
finally
{
sw.Stop();
}
+
+ return result;
}
///
@@ -353,10 +392,10 @@ public async Task UpdateThings(Thing thing, IEnumerable thingsToUpdate)
///
/// the container clone of the thing to delete
/// the cloned thing to delete in the session
- /// An asynchronous operation
- public async Task DeleteThing(Thing containerClone, Thing thingToDelete)
+ /// An asynchronous operation with a
+ public async Task DeleteThing(Thing containerClone, Thing thingToDelete)
{
- await this.DeleteThings(containerClone, new List { thingToDelete });
+ return await this.DeleteThings(containerClone, new List { thingToDelete });
}
///
@@ -364,10 +403,10 @@ public async Task DeleteThing(Thing containerClone, Thing thingToDelete)
///
/// the container clone of the thing to delete
/// the cloned things to delete in the session
- /// An asynchronous operation
- public async Task DeleteThings(Thing containerClone, params Thing[] thingsToDelete)
+ /// An asynchronous operation with a
+ public async Task DeleteThings(Thing containerClone, params Thing[] thingsToDelete)
{
- await this.DeleteThings(containerClone, thingsToDelete.ToList());
+ return await this.DeleteThings(containerClone, thingsToDelete.ToList());
}
///
@@ -375,12 +414,15 @@ public async Task DeleteThings(Thing containerClone, params Thing[] thingsToDele
///
/// the container clone of the thing to delete
/// the cloned things to delete in the session
- /// An asynchronous operation
- public async Task DeleteThings(Thing containerClone, IEnumerable thingsToDelete)
+ /// An asynchronous operation with a
+ public async Task DeleteThings(Thing containerClone, IEnumerable thingsToDelete)
{
+ var result = new Result();
+
if (thingsToDelete == null)
{
- return;
+ result.Errors.Add(new Error("The things to delete can't be null"));
+ return result;
}
var sw = Stopwatch.StartNew();
@@ -411,16 +453,20 @@ public async Task DeleteThings(Thing containerClone, IEnumerable thingsTo
try
{
await this.Session.Write(operationContainer);
- Console.WriteLine($"Delete done in {sw.ElapsedMilliseconds} [ms]");
+ this.logger.LogInformation($"Delete done in {sw.ElapsedMilliseconds} [ms]");
+ result.Successes.Add(new Success($"Delete done in {sw.ElapsedMilliseconds} [ms]"));
}
catch (Exception ex)
{
- Console.WriteLine($"The delete operation failed: {ex.Message}");
+ this.logger.LogError($"The delete operation failed: {ex.Message}", ex);
+ result.Errors.Add(new Error($"The delete operation failed: {ex.Message}"));
}
finally
{
sw.Stop();
}
+
+ return result;
}
///
diff --git a/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs b/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs
index b5ea94c6..7eecc457 100644
--- a/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs
+++ b/COMETwebapp.Tests/Components/SystemRepresentation/SystemRepresentationBodyTestFixture.cs
@@ -46,6 +46,7 @@ namespace COMETwebapp.Tests.Components.SystemRepresentation
using COMETwebapp.ViewModels.Components.SystemRepresentation;
using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Logging;
using Moq;
@@ -74,10 +75,15 @@ public class SystemRepresentationPageTestFixture
[SetUp]
public void SetUp()
{
- this.context = new TestContext();
+ var logger = new Mock>();
+ this.context = new TestContext();
this.session = new Mock();
- this.sessionService = new SessionService { Session = this.session.Object };
+
+ this.sessionService = new SessionService(logger.Object)
+ {
+ Session = this.session.Object
+ };
this.context.Services.AddSingleton(this.sessionService);
this.context.ConfigureDevExpressBlazor();