Example #1
0
        /// <summary>
        /// Walk the path through the namespaces and see if this is a valid path.  Really we're finding
        /// the parent for the volume.  Someday this needs to be more dynamic in case we move the volume's rooting.
        /// </summary>
        /// <param name="volumeNamePath"></param>
        /// <param name="namespaces"></param>
        /// <param name="rootNameSpace"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        private static (NeoVirtFSNamespaces parentPath, string volumeName) FindVolumeNameWithPath(string volumeNamePath,
                                                                                                  Dictionary <ObjectId, NeoVirtFSNamespaces> namespaces,
                                                                                                  NeoVirtFSNamespaces rootNameSpace)
        {
            NeoVirtFSNamespaces retParent = null;

            // Build a quick index to traverse namespaces in a tree by name - ultimately we need to cache this

            var nameTree = new Dictionary <ObjectId, Dictionary <string, ObjectId> >();

            Console.WriteLine("Build Tree Index");
            foreach (var n in namespaces)
            {
                var p = n.Value.ParentId;

                if (nameTree.ContainsKey(p))
                {
                    nameTree[p].Add(n.Value.NameSpace, n.Key);
                }
                else
                {
                    var newT = new Dictionary <string, ObjectId>();
                    newT.Add(n.Value.NameSpace, n.Key);
                    nameTree.Add(n.Value.ParentId, newT);
                };
            }

            var paths = volumeNamePath.Split('/');

            // Start at the top

            var rootLevel    = rootNameSpace._id;
            var levelMembers = nameTree[rootLevel];

            //var levelStack = new List<NeoVirtFSNamespaces>();

            // Have top stop one before the end
            foreach (var p in paths[..^ 1])
Example #2
0
        public static ObjectId EnsureVolumeSetUpProperly(IMongoDatabase db, string volumeNamePath)
        {
            var HaveRoot = false;

            var NamespaceNames = new Dictionary <string, NeoVirtFSNamespaces>();
            var Namespaces     = new Dictionary <ObjectId, NeoVirtFSNamespaces>();
            NeoVirtFSNamespaces RootNameSpace = null;

            var NeoVirtFSCol              = db.NeoVirtFS();
            var NeoVirtFSDeletedCol       = db.NeoVirtFSDeleted();
            var NeoVirtFSNamespacesCol    = db.NeoVirtFSNamespaces();
            var NeoVirtFSVolumesCol       = db.NeoVirtFSVolumes();
            var NeoVirtFSSecPrincipalsCol = db.NeoVirtFSSecPrincipals();
            var NeoVirtFSSecACLsCol       = db.NeoVirtFSSecACLs();

            // Prepare for bulk update

            var updates = new List <WriteModel <NeoVirtFS> >();

            // Load up the namespaces -- there just shouldn't be too many of these

            ProcessNamespaces(db, NamespaceNames, Namespaces, ref RootNameSpace, ref HaveRoot, updates);
            if (!HaveRoot)
            {
                throw new ApplicationException("Volume Namespaces don't define a Root - Setup Issue");
            }

            // Now do volumes

            var(parentPath, VolumeName) = FindVolumeNameWithPath(volumeNamePath, Namespaces, RootNameSpace);
            if (parentPath == null)  // We won't really get here - the above will throw
            {
                throw new ArgumentException($"Volume Path Not Valid: {volumeNamePath}");
            }

            // So we actually need to create this volume into NeoVirtFSVolumes, which unfortunately needs business logic
            // We need some sort of policy for this.  Maybe we're overthinking.  Maybe we just need to be passed the path so we
            //  don't need to decide?   We have the Namespaces above so we can decode

            var volume = NeoVirtFSVolumesCol.FindSync(Builders <NeoVirtFSVolumes> .Filter.Eq(x => x.Name, VolumeName)).FirstOrDefault();

            if (volume == null)
            {
                Console.WriteLine($"[Create Volume {VolumeName} into Namespace {parentPath.NameSpace}]");

                var newNode = ObjectId.GenerateNewId();

                // If the namespace moved then this isn't going to change it, though we may assert below

                NeoVirtFSVolumesCol.InsertOne(new NeoVirtFSVolumes()
                {
                    _id              = newNode,
                    Name             = VolumeName,
                    NameSpace        = parentPath._id,
                    NodeId           = newNode, // These are intentionally the same
                    VolumeDefaultACL = null,
                    ImportLocked     = false,
                    VolumeLocked     = false,
                });
            }

            // This is only going to return our one volume (which we may have just created)
            var volFilter = Builders <NeoVirtFSVolumes> .Filter.Eq(x => x.Name, VolumeName);

            var v = NeoVirtFSVolumesCol.FindSync(volFilter).FirstOrDefault();

            // This is making sure that the NeoVirtFS elements match the Volume setup (they use the same keys for clarity)

            Console.WriteLine($"Volume: {v.Name}, NameSpace: {Namespaces[v.NameSpace].NameSpace}");

            // Assert if the namespace has moved - We can just move it

            if (v.NameSpace != parentPath._id)
            {
                Console.WriteLine($"Volume Namespace {Namespaces[v.NameSpace].NameSpace} is not same as current Namespace {Namespaces[parentPath._id].NameSpace}");

                v.NameSpace = parentPath._id;   // Just move the node to the correct place within namespaces

                // And do it in the table (not bulk)
                var fixPar = new UpdateDefinitionBuilder <NeoVirtFSVolumes>()
                             .Set("NameSpace", parentPath._id);

                NeoVirtFSVolumesCol.UpdateOne(volFilter, fixPar);
            }

            // Ensure that the filesystem nodes exist at the top level

            FilterDefinition <NeoVirtFS> filter = Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, v._id);

            var upd = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>()
                      .Set("_id", v._id)
                      .SetOnInsert("Content", NeoVirtFSContent.Dir())
                      .SetOnInsert("Stat", NeoVirtFSStat.DirDefault())
                      .Set("VolumeId", v.NameSpace)
                      .Set("ParentId", Namespaces[v.NameSpace]._id) // Set's see what root does - this will also move the Node to match the Volume
                      .Set("Name", Encoding.UTF8.GetBytes(v.Name))
                      .Set("MaintLevel", false);                    // This is the volume level - users can do stuff here (by their policy)

            UpdateOneModel <NeoVirtFS> update = new UpdateOneModel <NeoAssets.Mongo.NeoVirtFS>(filter, upd)
            {
                IsUpsert = true
            };

            updates.Add(update);

            // Persist

            NeoVirtFSCol.BulkWrite(updates);

            return(v._id);
        }
Example #3
0
        public static bool PullNamespacesAndVolumes(IMongoDatabase db,
                                                    ref Dictionary <string, NeoVirtFSNamespaces> NamespaceNames,
                                                    ref Dictionary <ObjectId, NeoVirtFSNamespaces> Namespaces,
                                                    ref NeoVirtFSNamespaces RootNameSpace)
        {
            bool HaveRoot = false;

            var NeoVirtFSCol              = db.NeoVirtFS();
            var NeoVirtFSDeletedCol       = db.NeoVirtFSDeleted();
            var NeoVirtFSNamespacesCol    = db.NeoVirtFSNamespaces();
            var NeoVirtFSVolumesCol       = db.NeoVirtFSVolumes();
            var NeoVirtFSSecPrincipalsCol = db.NeoVirtFSSecPrincipals();
            var NeoVirtFSSecACLsCol       = db.NeoVirtFSSecACLs();

            // Prepare for bulk update

            var updates = new List <WriteModel <NeoAssets.Mongo.NeoVirtFS> >();

            // Load up the namespaces -- there just shouldn't be too many of these

            var nCount = ProcessNamespaces(db, NamespaceNames, Namespaces, ref RootNameSpace, ref HaveRoot, updates);

            if (!HaveRoot)
            {
                throw new ApplicationException("Volume Namespaces don't define a Root - Setup Issue");
            }

            // Now do volumes

            int vCount  = 0;
            var volumes = NeoVirtFSVolumesCol.FindSync(Builders <NeoVirtFSVolumes> .Filter.Empty).ToList();

            foreach (var v in volumes)
            {
                //Console.WriteLine($"Volume: {v.Name}");
                vCount++;

                // Ensure that the filesystem nodes exist at the top level

                FilterDefinition <NeoVirtFS> filter = Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, v._id);

                var upd = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>()
                          .Set("_id", v._id)
                          .SetOnInsert("Content", NeoVirtFSContent.Dir())
                          .SetOnInsert("Stat", NeoVirtFSStat.DirDefault())
                          .Set("VolumeId", v.NameSpace)
                          .Set("ParentId", Namespaces[v.NameSpace]._id) // Set's see what root does
                          .Set("Name", Encoding.UTF8.GetBytes(v.Name))
                          .Set("MaintLevel", false);                    // This is the volume level - users can do stuff here (by their policy)

                UpdateOneModel <NeoVirtFS> update = new UpdateOneModel <NeoAssets.Mongo.NeoVirtFS>(filter, upd)
                {
                    IsUpsert = true
                };
                updates.Add(update);
            }

            Console.WriteLine($"[Loaded {nCount} Namespaces and {vCount} Volumes]");

            // Persist

            NeoVirtFSCol.BulkWrite(updates);

            return(HaveRoot);
        }