From 6dcbfe9d67443bbfcb5a01ce7ff3fbe9daa74b5e Mon Sep 17 00:00:00 2001 From: Adrian Chivu <47980674+adrianchivu@users.noreply.github.com> Date: Thu, 5 Nov 2020 12:01:26 +0200 Subject: [PATCH] Implement migration.json support when importing (#141) * WriteExtraFilesToZipFile initial implementation. * Change WriteExtraFilesToZipFile. * Add null parameter validation. * Update test. * Review Cozmin and Sam comments. --- .../JsonFileDalTestFixture.cs | 128 +++++++++++++++++- CDP4JsonFileDal.Tests/files/migration.json | 13 ++ CDP4JsonFileDal/JsonFileDal.cs | 35 ++++- 3 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 CDP4JsonFileDal.Tests/files/migration.json diff --git a/CDP4JsonFileDal.Tests/JsonFileDalTestFixture.cs b/CDP4JsonFileDal.Tests/JsonFileDalTestFixture.cs index 4bc90435f..b901f034b 100644 --- a/CDP4JsonFileDal.Tests/JsonFileDalTestFixture.cs +++ b/CDP4JsonFileDal.Tests/JsonFileDalTestFixture.cs @@ -57,7 +57,17 @@ namespace CDP4JsonFileDal.Tests public class JsonFileDalTestFixture { /// - /// The instance of that is being tested + /// AnnexC3 file archive + /// + private string annexC3File; + + /// + /// Migration file that will be included + /// + private string migrationFile; + + /// + /// The instance of that is being tested /// private JsonFileDal dal; @@ -99,12 +109,23 @@ public void OneTimeSetUp() public void SetUp() { var path = Path.Combine(TestContext.CurrentContext.TestDirectory, "files", "LOFT_ECSS-E-TM-10-25_AnnexC.zip"); + var migrationSourceFile = Path.Combine(TestContext.CurrentContext.TestDirectory, @"..\..\..\files", "migration.json"); + + this.annexC3File = Path.Combine(TestContext.CurrentContext.TestDirectory, "files", "AnnexC3.zip"); + this.migrationFile = Path.Combine(TestContext.CurrentContext.TestDirectory, "files", "migration.json"); + + if (!File.Exists(this.migrationFile)) + { + File.Copy(migrationSourceFile, this.migrationFile); + } this.cancelationTokenSource = new CancellationTokenSource(); this.credentials = new Credentials("admin", "pass", new Uri(path)); this.session = new Mock(); - this.dal = new JsonFileDal(); - this.dal.Session = this.session.Object; + this.dal = new JsonFileDal + { + Session = this.session.Object + }; this.siteDirectoryData = new SiteDirectory(); this.session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectoryData); @@ -116,6 +137,16 @@ public void TearDown() { this.credentials = null; this.dal = null; + + if (File.Exists(this.annexC3File)) + { + File.Delete(this.annexC3File); + } + + if (File.Exists(this.migrationFile)) + { + File.Delete(this.migrationFile); + } } [Test] @@ -343,5 +374,96 @@ public void VerifyCtorWithVersionAndCopyright() Assert.IsTrue(this.dal.FileHeader.Copyright == COPYRIGHT); Assert.IsTrue(this.dal.FileHeader.Remark == REMARK); } + + [Test] + public void VerifyWritingWithoutMigrationFile() + { + var zipCredentials = new Credentials("admin", "pass", new Uri(this.annexC3File)); + var zipSession = new Session(this.dal, zipCredentials); + + var operationContainers = this.BuildOperationContainers(); + + Assert.DoesNotThrowAsync(async () => await Task.Run(() => this.dal.Write(operationContainers))); + } + + [Test] + public void VerifyWritingMigrationFile() + { + var zipCredentials = new Credentials("admin", "pass", new Uri(this.annexC3File)); + var zipSession = new Session(this.dal, zipCredentials); + + var operationContainers = this.BuildOperationContainers(); + + Assert.DoesNotThrowAsync(async () => await Task.Run(() => this.dal.Write(operationContainers, new string[] { this.migrationFile }))); + } + + /// + /// Build operation containes structure that will be serialized + /// + /// + /// List of + /// + private IEnumerable BuildOperationContainers() + { + var cache = new ConcurrentDictionary>(); + + // DomainOfExpertise + var domain = new DomainOfExpertise(Guid.NewGuid(), cache, this.credentials.Uri) { ShortName = "SYS" }; + this.siteDirectoryData.Domain.Add(domain); + + // PersonRole + var role = new PersonRole(Guid.NewGuid(), null, null); + this.siteDirectoryData.PersonRole.Add(role); + this.siteDirectoryData.DefaultPersonRole = role; + + // ParticipantRole + var participantRole = new ParticipantRole(Guid.Empty, null, null); + this.siteDirectoryData.ParticipantRole.Add(participantRole); + this.siteDirectoryData.DefaultParticipantRole = participantRole; + + // Organization + var organization = new Organization(Guid.NewGuid(), null, null) + { + Container = this.siteDirectoryData + }; + + // Iteration + var iterationIid = new Guid("b58ea73d-350d-4520-b9d9-a52c75ac2b5d"); + var iterationSetup = new IterationSetup(Guid.NewGuid(), 0); + var iterationSetupPoco = new CDP4Common.SiteDirectoryData.IterationSetup(iterationSetup.Iid, cache, this.credentials.Uri); + + // EngineeringModel + var model = new EngineeringModel(Guid.NewGuid(), cache, this.credentials.Uri); + var modelSetup = new CDP4Common.SiteDirectoryData.EngineeringModelSetup(); + modelSetup.ActiveDomain.Add(domain); + + var requiredRdl = new ModelReferenceDataLibrary(); + + var person = new Person { ShortName = "admin", Organization = organization }; + var participant = new Participant(Guid.NewGuid(), cache, this.credentials.Uri) { Person = person }; + participant.Person.Role = role; + participant.Role = participantRole; + participant.Domain.Add(domain); + modelSetup.Participant.Add(participant); + + var lazyPerson = new Lazy(() => person); + var iterationPoco = new CDP4Common.EngineeringModelData.Iteration(iterationIid, cache, this.credentials.Uri) { IterationSetup = iterationSetupPoco }; + model.Iteration.Add(iterationPoco); + var iteration = (Iteration)iterationPoco.ToDto(); + model.EngineeringModelSetup = modelSetup; + this.siteDirectoryData.Model.Add(modelSetup); + modelSetup.RequiredRdl.Add(requiredRdl); + modelSetup.IterationSetup.Add(iterationSetupPoco); + cache.TryAdd(new CacheKey(person.Iid, this.siteDirectoryData.Iid), lazyPerson); + this.siteDirectoryData.Cache = cache; + iteration.IterationSetup = iterationSetup.Iid; + var iterationClone = iteration.DeepClone(); + + var operation = new Operation(iteration, iterationClone, OperationKind.Update); + var operationContainers = new[] { new OperationContainer("/EngineeringModel/" + model.Iid + "/iteration/" + iteration.Iid, 0) }; + operationContainers.Single().AddOperation(operation); + + return operationContainers; + } } } diff --git a/CDP4JsonFileDal.Tests/files/migration.json b/CDP4JsonFileDal.Tests/files/migration.json new file mode 100644 index 000000000..91ee11ed1 --- /dev/null +++ b/CDP4JsonFileDal.Tests/files/migration.json @@ -0,0 +1,13 @@ +{ + "url": "https://username:password@server", + "credentials": { + "1c2466ed-ddb9-4546-b458-5b3dbcb58924": { + "password": "70d3491b7b5033ce7e4f77630058a2b78a8e5a817b7eb957a306490092d4dd83", + "salt": "8b747da1d2220d2deb9c153882177727edcf05151b9c575881eea57fce7ecceb" + }, + "cc89eec4-d7ba-486d-854b-8f2407e154e2": { + "password": "70d3491b7b5033ce7e4f77630058a2b78a8e5a817b7eb957a306490092d4dd83", + "salt": "8b747da1d2220d2deb9c153882177727edcf05151b9c575881eea57fce7ecceb" + } + } +} diff --git a/CDP4JsonFileDal/JsonFileDal.cs b/CDP4JsonFileDal/JsonFileDal.cs index b0fbed201..53a6211ec 100644 --- a/CDP4JsonFileDal/JsonFileDal.cs +++ b/CDP4JsonFileDal/JsonFileDal.cs @@ -80,6 +80,11 @@ public class JsonFileDal : Dal /// private const string EngineeringModelZipLocation = "EngineeringModels"; + /// + /// The application-dependent (extensions) files zip location. + /// + private const string ExtensionsZipLocation = "Extensions"; + /// /// The iteration zip location. /// @@ -157,13 +162,13 @@ public override bool IsReadOnly /// /// The provided to write /// - /// - /// The path to the files that need to be uploaded. If is null, then no files are to be uploaded + /// + /// The path to the files that need to be uploaded. If is null, then no files are to be uploaded /// /// /// A list of s that has been created or updated since the last Read or Write operation. /// - public override Task> Write(IEnumerable operationContainers, IEnumerable files = null) + public override Task> Write(IEnumerable operationContainers, IEnumerable extensionFiles = null) { this.ValidateOperationContainers(operationContainers); @@ -243,6 +248,8 @@ public override Task> Write(IEnumerable o this.WriteModelReferenceDataLibraryToZipFile(modelReferenceDataLibraries, zipFile, path); this.WriteIterationsToZipFile(iterations, zipFile, path); + + this.WriteExtensionFilesToZipFile(extensionFiles, zipFile, path); } Logger.Info("Successfully exported the open session {1} to {0}.", path, this.Session.Credentials.Uri); @@ -806,6 +813,28 @@ private void WriteIterationsToZipFile(IEnumerable + /// Writes the application dependend files inside specific folder to the + /// + /// The files list that will be written + /// The target + /// The file path of the target + private void WriteExtensionFilesToZipFile(IEnumerable extraFilesPath, ZipFile zipFile, string filePath) + { + if (extraFilesPath is null) + { + return; + } + + foreach (var extraFile in extraFilesPath) + { + var zipEntry = zipFile.AddFile(extraFile, ExtensionsZipLocation); + zipEntry.Comment = $"The {extraFile} file"; + } + + zipFile.Save(filePath); + } + /// /// Reads SiteDirectory data from the archive ///