Skip to content

Commit

Permalink
Fixes #109 Implements multipart message fix and cancellation of file …
Browse files Browse the repository at this point in the history
…download. (#110)

* Implements multipart message fix and cancellation of file download.
* Cosmetic fixes
* Comment fix
* Moved some code from IME counterpart to ISession/Session
  • Loading branch information
lxatstariongroup authored Apr 23, 2020
1 parent 9f60487 commit 9b08538
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 47 deletions.
174 changes: 168 additions & 6 deletions CDP4Dal.Tests/SessionTestFixture.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SessionTestFixture.cs" company="RHEA System S.A.">
// Copyright (c) 2015-2019 RHEA System S.A.
// Copyright (c) 2015-2020 RHEA System S.A.
//
// Author: Sam Gerené, Merlin Bieze, Alex Vorobiev, Naron Phou
// Author: Sam Gerené, Merlin Bieze, Alex Vorobiev, Naron Phou, Alexander van Delft
//
// This file is part of CDP4-SDK Community Edition
//
Expand All @@ -29,20 +29,25 @@ namespace CDP4Dal.Tests
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using CDP4Common.CommonData;
using CDP4Common.DTO;
using CDP4Common.MetaInfo;
using CDP4Dal.Operations;
using CDP4Common.SiteDirectoryData;
using CDP4Common.Types;

using CDP4Dal.Operations;
using CDP4Dal.Composition;
using CDP4Dal.DAL;
using CDP4Dal.Events;

using Moq;

using NUnit.Framework;

using DomainOfExpertise = CDP4Common.SiteDirectoryData.DomainOfExpertise;
using EngineeringModel = CDP4Common.DTO.EngineeringModel;
using EngineeringModelSetup = CDP4Common.DTO.EngineeringModelSetup;
using Iteration = CDP4Common.DTO.Iteration;
using ModelReferenceDataLibrary = CDP4Common.SiteDirectoryData.ModelReferenceDataLibrary;
using SiteDirectory = CDP4Common.DTO.SiteDirectory;
using SiteReferenceDataLibrary = CDP4Common.SiteDirectoryData.SiteReferenceDataLibrary;
Expand Down Expand Up @@ -313,7 +318,7 @@ public async Task VerifyThatSiteRdlRequiredByModelRdlCannotBeClosed()
var modelsetup = new EngineeringModelSetup(Guid.NewGuid(), 0);
modelsetup.RequiredRdl.Add(mrdl.Iid);

var model = new EngineeringModel(Guid.NewGuid(), 0) { EngineeringModelSetup = modelsetup.Iid };
var model = new CDP4Common.DTO.EngineeringModel(Guid.NewGuid(), 0) { EngineeringModelSetup = modelsetup.Iid };
var iteration = new Iteration(Guid.NewGuid(), 0);
model.Iteration.Add(iteration.Iid);

Expand Down Expand Up @@ -571,6 +576,35 @@ public void VeriyThatCDPVersionIsSet()
Assert.AreEqual(version.Build, this.session.DalVersion.Build);
}

[Test]
public async Task VeriyThatCanCancelWorks()
{
var iterationSetup = new CDP4Common.SiteDirectoryData.IterationSetup(Guid.NewGuid(), null, null) { FrozenOn = DateTime.Now, IterationIid = Guid.NewGuid() };
var JohnDoe = new CDP4Common.SiteDirectoryData.Person(this.person.Iid, this.session.Assembler.Cache, this.uri) { ShortName = "John" };
var activeDomain = new DomainOfExpertise(Guid.NewGuid(), null, null);
var model = new EngineeringModel(Guid.NewGuid(), 1);
var iteration = new Iteration(Guid.NewGuid(), 10) { IterationSetup = iterationSetup.Iid };

var iterationToOpen = new CDP4Common.EngineeringModelData.Iteration(iteration.Iid, null, null);
var modelToOpen = new CDP4Common.EngineeringModelData.EngineeringModel(model.Iid, null, null);

this.session.GetType().GetProperty("ActivePerson").SetValue(this.session, JohnDoe, null);

iterationToOpen.Container = modelToOpen;

Assert.IsFalse(this.session.CanCancel());

this.mockedDal.Setup(x => x.Read(It.IsAny<Iteration>(), It.IsAny<CancellationToken>(), null))
.Callback(() => Assert.IsTrue(this.session.CanCancel()))
.ReturnsAsync(new List<Thing>());

await this.session.Read(iterationToOpen, activeDomain);

Assert.IsFalse(this.session.CanCancel());

this.mockedDal.Verify(x => x.Read(It.IsAny<Iteration>(), It.IsAny<CancellationToken>(), null), Times.Exactly(1));
}

[Test]
public void VerifyThatIsVersionSupportedReturnsExpectedResult()
{
Expand All @@ -587,8 +621,136 @@ public void VerifyThatIsVersionSupportedReturnsExpectedResult()
var notSupportedVersion = new Version("2.0.0");
Assert.IsFalse(this.session.IsVersionSupported(notSupportedVersion));
}
}

[Test]
public async Task VerifyThatQueryCurrentDomainOfExpertiseWorks()
{
var siteDir = new CDP4Common.SiteDirectoryData.SiteDirectory(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var JohnDoe = new CDP4Common.SiteDirectoryData.Person(this.person.Iid, this.session.Assembler.Cache, this.uri) { ShortName = "John" };
var modelSetup = new CDP4Common.SiteDirectoryData.EngineeringModelSetup(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var iterationSetup = new CDP4Common.SiteDirectoryData.IterationSetup(Guid.NewGuid(), this.session.Assembler.Cache, this.uri) { IterationIid = Guid.NewGuid() };
var mrdl = new ModelReferenceDataLibrary(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var srdl = new SiteReferenceDataLibrary(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var activeDomain = new DomainOfExpertise(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
mrdl.RequiredRdl = srdl;
modelSetup.RequiredRdl.Add(mrdl);
modelSetup.IterationSetup.Add(iterationSetup);
siteDir.Model.Add(modelSetup);
siteDir.SiteReferenceDataLibrary.Add(srdl);
siteDir.Domain.Add(activeDomain);
siteDir.Person.Add(JohnDoe);

this.session.Assembler.Cache.TryAdd(new CacheKey(siteDir.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => siteDir));
this.session.Assembler.Cache.TryAdd(new CacheKey(JohnDoe.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => JohnDoe));
this.session.Assembler.Cache.TryAdd(new CacheKey(modelSetup.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => modelSetup));
this.session.Assembler.Cache.TryAdd(new CacheKey(mrdl.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => mrdl));
this.session.Assembler.Cache.TryAdd(new CacheKey(srdl.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => srdl));
this.session.Assembler.Cache.TryAdd(new CacheKey(siteDir.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => siteDir));
this.session.Assembler.Cache.TryAdd(new CacheKey(iterationSetup.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => iterationSetup));

this.session.GetType().GetProperty("ActivePerson").SetValue(this.session, JohnDoe, null);

var participant = new CDP4Common.SiteDirectoryData.Participant(Guid.NewGuid(), this.session.Assembler.Cache, this.uri) { Person = this.session.ActivePerson };
participant.Domain.Add(activeDomain);
modelSetup.Participant.Add(participant);

var model = new EngineeringModel(Guid.NewGuid(), 1);
var iteration = new Iteration(iterationSetup.IterationIid, 10) { IterationSetup = iterationSetup.Iid };
model.Iteration.Add(iteration.Iid);
model.EngineeringModelSetup = modelSetup.Iid;

var readOutput = new List<Thing>
{
model,
iteration
};

var readTaskCompletionSource = new TaskCompletionSource<IEnumerable<Thing>>();
readTaskCompletionSource.SetResult(readOutput);
this.mockedDal.Setup(x => x.Read(It.IsAny<Iteration>(), It.IsAny<CancellationToken>(), It.IsAny<IQueryAttributes>())).Returns(readTaskCompletionSource.Task);

var iterationToOpen = new CDP4Common.EngineeringModelData.Iteration(iteration.Iid, null, null);
var modelToOpen = new CDP4Common.EngineeringModelData.EngineeringModel(model.Iid, null, null);
iterationToOpen.Container = modelToOpen;

await this.session.Read(iterationToOpen, activeDomain);

var resultDomain = this.session.QueryCurrentDomainOfExpertise();

Assert.AreEqual(activeDomain, resultDomain);

iterationSetup.FrozenOn = DateTime.UtcNow;

resultDomain = this.session.QueryCurrentDomainOfExpertise();

Assert.IsNull(resultDomain);
}

[Test]
public async Task VerifyThatQueryDomainOfExpertiseWorks()
{
var siteDir = new CDP4Common.SiteDirectoryData.SiteDirectory(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var JohnDoe = new CDP4Common.SiteDirectoryData.Person(this.person.Iid, this.session.Assembler.Cache, this.uri) { ShortName = "John" };
var modelSetup = new CDP4Common.SiteDirectoryData.EngineeringModelSetup(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var iterationSetup = new CDP4Common.SiteDirectoryData.IterationSetup(Guid.NewGuid(), this.session.Assembler.Cache, this.uri) { IterationIid = Guid.NewGuid() };
var mrdl = new ModelReferenceDataLibrary(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var srdl = new SiteReferenceDataLibrary(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
var activeDomain = new DomainOfExpertise(Guid.NewGuid(), this.session.Assembler.Cache, this.uri);
mrdl.RequiredRdl = srdl;
modelSetup.RequiredRdl.Add(mrdl);
modelSetup.IterationSetup.Add(iterationSetup);
siteDir.Model.Add(modelSetup);
siteDir.SiteReferenceDataLibrary.Add(srdl);
siteDir.Domain.Add(activeDomain);
siteDir.Person.Add(JohnDoe);

this.session.Assembler.Cache.TryAdd(new CacheKey(siteDir.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => siteDir));
this.session.Assembler.Cache.TryAdd(new CacheKey(JohnDoe.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => JohnDoe));
this.session.Assembler.Cache.TryAdd(new CacheKey(modelSetup.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => modelSetup));
this.session.Assembler.Cache.TryAdd(new CacheKey(mrdl.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => mrdl));
this.session.Assembler.Cache.TryAdd(new CacheKey(srdl.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => srdl));
this.session.Assembler.Cache.TryAdd(new CacheKey(siteDir.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => siteDir));
this.session.Assembler.Cache.TryAdd(new CacheKey(iterationSetup.Iid, null), new Lazy<CDP4Common.CommonData.Thing>(() => iterationSetup));

this.session.GetType().GetProperty("ActivePerson").SetValue(this.session, JohnDoe, null);

var participant = new CDP4Common.SiteDirectoryData.Participant(Guid.NewGuid(), this.session.Assembler.Cache, this.uri){ Person = this.session.ActivePerson };
participant.Domain.Add(activeDomain);
modelSetup.Participant.Add(participant);

var model = new EngineeringModel(Guid.NewGuid(), 1);
var iteration = new Iteration(iterationSetup.IterationIid, 10) { IterationSetup = iterationSetup.Iid };
model.Iteration.Add(iteration.Iid);
model.EngineeringModelSetup = modelSetup.Iid;

var readOutput = new List<Thing>
{
model,
iteration
};

var readTaskCompletionSource = new TaskCompletionSource<IEnumerable<Thing>>();
readTaskCompletionSource.SetResult(readOutput);
this.mockedDal.Setup(x => x.Read(It.IsAny<Iteration>(), It.IsAny<CancellationToken>(), It.IsAny<IQueryAttributes>())).Returns(readTaskCompletionSource.Task);

var iterationToOpen = new CDP4Common.EngineeringModelData.Iteration(iteration.Iid, null, null);
var modelToOpen = new CDP4Common.EngineeringModelData.EngineeringModel(model.Iid, null, null);
iterationToOpen.Container = modelToOpen;

await this.session.Read(iterationToOpen, activeDomain);

var resultDomains = this.session.QueryDomainOfExpertise();

CollectionAssert.AreEqual(new [] {activeDomain}, resultDomains);

iterationSetup.FrozenOn = DateTime.UtcNow;

resultDomains = this.session.QueryDomainOfExpertise();

CollectionAssert.IsEmpty(resultDomains);
}
}

[DalExport("test dal", "test dal description", "1.1.0", DalType.Web)]
internal class TestDal : IDal
{
Expand Down
22 changes: 22 additions & 0 deletions CDP4Dal/ISession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ public interface ISession
/// </summary>
Task Close();

/// <summary>
/// Can a Cancel action be executed?
/// </summary>
/// <returns>True is Cancel is allowed, otherwise false.</returns>
bool CanCancel();

/// <summary>
/// Cancel any Read or Open operation.
/// </summary>
Expand Down Expand Up @@ -305,5 +311,21 @@ public interface ISession
/// The <see cref="Task"/>.
/// </returns>
Task CloseModelRdl(ModelReferenceDataLibrary modelRdl);

/// <summary>
/// Queries the current <see cref="DomainOfExpertise"/> from the session for the current <see cref="Iteration"/>
/// </summary>
/// <returns>
/// The <see cref="DomainOfExpertise"/> if selected, null otherwise.
/// </returns>
DomainOfExpertise QueryCurrentDomainOfExpertise();

/// <summary>
/// Queries the <see cref="Participant"/>'s <see cref="DomainOfExpertise"/>'s from the session for the current <see cref="Iteration"/>
/// </summary>
/// <returns>
/// The <see cref="DomainOfExpertise"/> if selected, null otherwise.
/// </returns>
IEnumerable<DomainOfExpertise> QueryDomainOfExpertise();
}
}
60 changes: 58 additions & 2 deletions CDP4Dal/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,19 @@ public async Task Read(Iteration iteration, DomainOfExpertise domain)
{
var iterationDto = (CDP4Common.DTO.Iteration) iteration.ToDto();
this.Dal.Session = this;
dtoThings = await this.Dal.Read(iterationDto, this.cancellationTokenSource.Token);
dtoThings = await this.Dal.Read(iterationDto, this.cancellationTokenSource.Token, null);
this.cancellationTokenSource.Token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
{
logger.Info("Session.Read {0} {1} cancelled", iteration.ClassKind, iteration.Iid);
this.cancellationTokenSource = null;
return;
}
finally
{
this.cancellationTokenSource = null;
}

// proceed if no problem
var enumerable = dtoThings as IList<CDP4Common.DTO.Thing> ?? dtoThings.ToList();
Expand Down Expand Up @@ -686,12 +691,26 @@ public async Task Reload()
}
}

/// <summary>
/// Can a Cancel action be executed?
/// </summary>
/// <returns>True is Cancel is allowed, otherwise false.</returns>
public bool CanCancel()
{
if (this.cancellationTokenSource == null)
{
return false;
}

return this.cancellationTokenSource.Token.CanBeCanceled && !this.cancellationTokenSource.IsCancellationRequested;
}

/// <summary>
/// Cancel any Read or Open operation.
/// </summary>
public void Cancel()
{
if (this.cancellationTokenSource != null)
if (this.CanCancel())
{
this.cancellationTokenSource.Cancel();
}
Expand Down Expand Up @@ -928,5 +947,42 @@ private void AddIterationToOpenList(Guid iterationId, DomainOfExpertise activeDo
var modelRdl = ((EngineeringModel) iteration.Container).EngineeringModelSetup.RequiredRdl.Single();
this.AddRdlToOpenList(modelRdl);
}

/// <summary>
/// Queries the current <see cref="DomainOfExpertise"/> from the session for the current <see cref="Iteration"/>
/// </summary>
/// <returns>
/// The <see cref="DomainOfExpertise"/> if selected, null otherwise.
/// </returns>
public DomainOfExpertise QueryCurrentDomainOfExpertise()
{
var iterationDomainPair = this.OpenIterations.SingleOrDefault(x => !x.Key.IterationSetup.FrozenOn.HasValue);

if (iterationDomainPair.Equals(default(KeyValuePair<Iteration, Tuple<DomainOfExpertise, Participant>>)))
{
return null;
}

return (iterationDomainPair.Value == null) || (iterationDomainPair.Value.Item1 == null) ? null : iterationDomainPair.Value.Item1;
}

/// <summary>
/// Queries the <see cref="Participant"/>'s <see cref="DomainOfExpertise"/>'s from the session for the current <see cref="Iteration"/>
/// </summary>
/// <returns>
/// The <see cref="DomainOfExpertise"/> if selected, null otherwise.
/// </returns>
public IEnumerable<DomainOfExpertise> QueryDomainOfExpertise()
{
var iterationDomainPair = this.OpenIterations.SingleOrDefault(x => !x.Key.IterationSetup.FrozenOn.HasValue);
var domainOfExpertise = new List<DomainOfExpertise>();

if (iterationDomainPair.Value?.Item2 != null)
{
domainOfExpertise.AddRange(iterationDomainPair.Value.Item2.Domain);
}

return domainOfExpertise;
}
}
}
4 changes: 4 additions & 0 deletions CDP4ServicesDal/CDP4ServicesDal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<None Include="..\docs\cdp4-icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CDP4Common\CDP4Common.csproj" />
<ProjectReference Include="..\CDP4JsonSerializer\CDP4JsonSerializer.csproj" />
Expand Down
Loading

0 comments on commit 9b08538

Please sign in to comment.