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
///