예제 #1
0
        public void DataValidation()
        {
            string fileContent =
                "Le TP 2/3 consiste à mettre en place un système de partage de fichier inspiré de systèmes comme\r\n" +
                "Dropbox, GoogleDrive, etc. Le système permettra à différents clients de partager et de\r\n" +
                "synchroniser des fichiers au sein de groupes définis. Le système est constitué de deux\r\n" +
                "composantes : un serveur central et un client. Le serveur est accessible à une adresse fixe,\r\n" +
                "connue de tous les clients. Le serveur a pour rôle de synchroniser, recevoir et transmettre les\r\n" +
                "fichiers des clients, et gérer les groupes auxquels les clients peuvent se rattacher. Les clients\r\n" +
                "doivent se synchroniser avec le serveur. Le système à implémenter est donc un système de clientserveur\r\n" +
                "basé sur le protocole TCP.";

            string fileAdded = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName());

            GroupSummary oldSummary = new GroupSummary(GROUP1, TESTING_PATH);

            File.WriteAllText(fileAdded, fileContent);
            GroupSummary newSummary = new GroupSummary(GROUP1, TESTING_PATH);

            byte[] extractData = newSummary.GenerateRevisions(oldSummary)[0].Data;
            //WriteAllText write in UTF8 by default.
            Assert.AreEqual(Encoding.UTF8.GetBytes(fileContent), extractData);

            File.Delete(fileAdded);
        }
예제 #2
0
        public void GenerateRevision()
        {
            string fileAdded       = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName());
            string fileDeleted     = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName());
            string fileModifed     = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName());
            string fileModifedPast = Path.Combine(TESTING_PATH, GROUP1, Path.GetRandomFileName());

            File.Create(fileDeleted).Close();
            File.Create(fileModifed).Close();
            File.Create(fileModifedPast).Close();

            GroupSummary oldSummary = new GroupSummary(GROUP1, TESTING_PATH);

            //When we create a file, a stream is created, so we need to close the stream because we are done with it.
            File.Create(fileAdded).Close();
            File.Delete(fileDeleted);
            File.SetLastWriteTime(fileModifed, DateTime.Now);
            File.SetLastWriteTime(fileModifedPast, DateTime.Now - new TimeSpan(12, 0, 0, 0));
            GroupSummary    newSummary = new GroupSummary(GROUP1, TESTING_PATH);
            List <Revision> result     = newSummary.GenerateRevisions(oldSummary);

            Assert.AreEqual(4, result.Count);
            //We are suppose to have only one new file.
            Assert.AreEqual(1, result.Count(revision => revision.Action == Action.Create));
            Revision createRevision = result.Find(revision => revision.Action == Action.Create);

            Assert.AreEqual(Path.GetFileName(fileAdded), createRevision.File.Name);
            Assert.AreEqual(GROUP1, createRevision.GroupName);

            //Delete Test
            Assert.AreEqual(1, result.Count(revision => revision.Action == Action.Delete));
            Revision deleteRevision = result.Find(revision => revision.Action == Action.Delete);

            Assert.AreEqual(Path.GetFileName(fileDeleted), deleteRevision.File.Name);
            Assert.AreEqual(GROUP1, deleteRevision.GroupName);

            //Modify test
            Assert.AreEqual(2, result.Count(revision => revision.Action == Action.Modify));
            Revision modifyRevision = result.Find(revision => revision.File.Name == Path.GetFileName(fileModifed));

            Assert.AreEqual(Path.GetFileName(fileModifed), modifyRevision.File.Name);
            Assert.AreEqual(GROUP1, modifyRevision.GroupName);

            //Modify test past
            Revision modifyRevisionpast = result.Find(revision => revision.File.Name == Path.GetFileName(fileModifedPast));

            Assert.AreEqual(Path.GetFileName(fileModifedPast), modifyRevisionpast.File.Name);
            Assert.AreEqual(GROUP1, modifyRevisionpast.GroupName);

            File.Delete(fileAdded);
            File.Delete(fileModifed);
            File.Delete(fileModifedPast);
        }
예제 #3
0
        /// <summary>
        /// Generate and push revisions list
        /// </summary>
        /// <returns>Revision list of the server.</returns>
        public List <Revision> UpdateServerHistory()
        {
            List <Revision>     localRevisions    = new List <Revision>();
            List <GroupSummary> newGroupSummaries = new List <GroupSummary>();

            //Creating the revision list
            foreach (GroupSummary group in lastGroupsSummaries)
            {
                GroupSummary updateSummary = new GroupSummary(group.GroupName, rootFolderPath);
                localRevisions.AddRange(updateSummary.GenerateRevisions(group));
                newGroupSummaries.Add(updateSummary);
            }
            lastGroupsSummaries = newGroupSummaries;
            List <Revision> serverRevisions = access.UpdateServerHistory(userName, localRevisions, lastGroupsSummaries);

            return(serverRevisions);
        }
예제 #4
0
        public void Execute()
        {
            // Blocking call
            foreach (Job job in syncJobs.GetConsumingEnumerable())
            {
                Console.WriteLine(@"Execute Job {0}", ++executionCount);
                List <Revision> returnRevisions = new List <Revision>();

                // For each client group revision
                foreach (GroupSummary clientGroupSummary in job.GroupSummaries)
                {
                    // Check user authorizations
                    if (dataStore.CheckUserInGroup(job.Username, clientGroupSummary.GroupName))
                    {
                        // Get the server GroupSummary equal to client GroupSummary
                        GroupSummary serverGroupSummary = serverGroupSummaries.Find(s => s.GroupName == clientGroupSummary.GroupName);

                        if (serverGroupSummary != null)
                        {
                            // Build revision list with client
                            List <Revision> revisions = serverGroupSummary.GenerateRevisions(clientGroupSummary);

                            foreach (Revision rev in revisions)
                            {
                                ShareLibrary.Models.FileInfo currentServerFile = serverGroupSummary.Files.Find(f => f.Name == rev.File.Name);
                                ShareLibrary.Models.FileInfo currentClientFile = clientGroupSummary.Files.Find(f => f.Name == rev.File.Name);

                                Revision currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentClientFile?.Name);
                                switch (rev.Action)
                                {
                                case Action.Create:
                                    // Rebind the currentRelatedjobRevision from the server instead of the client
                                    currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentServerFile?.Name);

                                    // Case 1 : The file was deleted by the current client
                                    // Update server history (delete the current file)
                                    if (currentRelatedjobRevision?.File.Name == rev.File.Name && currentRelatedjobRevision?.Action == Action.Delete)
                                    {
                                        currentRelatedjobRevision.Apply(rootPath);
                                        serverGroupSummary.Update();
                                    }
                                    // Case 2 : There is a new file on the server and the current client doesn't have it.
                                    // Add revision to response with data (Create)
                                    else
                                    {
                                        returnRevisions.Add(rev);
                                    }
                                    break;

                                case Action.Modify:
                                    rev.Data = currentRelatedjobRevision?.Data ?? rev.Data;

                                    // Case 1 : Server modification date > client modification date
                                    // Add revision to response with data (Modify)
                                    if (currentServerFile.LastModificationDate > currentClientFile.LastModificationDate)
                                    {
                                        returnRevisions.Add(rev);
                                    }
                                    // Case 2 : Server modification date < client modification date
                                    // Update server history (replace the current file)
                                    else
                                    {
                                        rev.Apply(rootPath);
                                        serverGroupSummary.Update();
                                    }
                                    break;

                                case Action.Delete:
                                    // Case 1 : The file was created by the current client.
                                    // Update server history (add the current file)
                                    if (currentRelatedjobRevision?.Action == Action.Create)
                                    {
                                        currentRelatedjobRevision.Apply(rootPath);
                                        serverGroupSummary.Update();
                                    }
                                    // Case 2 : The file is deleted for real (deleted from an other client)
                                    // Add revision to response (Delete)
                                    else
                                    {
                                        rev.Data = new byte[0];
                                        returnRevisions.Add(rev);
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // Initial case when the server does not have the client group synced
                            // Add the client files (revisions) to the server files
                            List <Revision> clientRevisions = job.Revisions.FindAll(r => r.GroupName == clientGroupSummary.GroupName);

                            // Create the group directory
                            Directory.CreateDirectory(Path.Combine(rootPath, clientGroupSummary.GroupName));

                            // Add every client file to the server
                            foreach (Revision clientRev in clientRevisions)
                            {
                                clientRev.Apply(rootPath);
                            }

                            // Create the server group summary because he didn't exist
                            serverGroupSummaries.Add(new GroupSummary(clientGroupSummary.GroupName, rootPath));
                        }
                    }
                }
                // Return the truth
                job.CallBack(returnRevisions);
            }
        }