Пример #1
0
        /// <summary>
        /// Обмен схем репликации текущего узла с узлом storageHost.
        /// </summary>
        /// <param name="remoteNode">Удаленный узел хранилища.</param>
        /// <param name="currentReplicationSchema">Схема репликации текущего узла.</param>
        /// <returns></returns>
        public IReplicationSchema ExchangeSchema(IStorageNode remoteNode, IReplicationSchema currentReplicationSchema)
        {
            if (remoteNode == null)
            {
                throw new ArgumentNullException("remoteNode");
            }

            if (currentReplicationSchema == null)
            {
                throw new ArgumentNullException("currentReplicationSchema");
            }

            return(this.MakeRequest(x =>
            {
                //схема репликации сети, известная текущему узлу
                WcfReplicationSchema typedCurrentReplicationSchema =
                    new WcfReplicationSchema(currentReplicationSchema);
                WcfReplicationSchemaMessage exchangeMessage =
                    new WcfReplicationSchemaMessage(typedCurrentReplicationSchema);
                //посылаем текущую схему узлу, к которому обращаемся
                //и получаем его схему с узла назначения
                WcfReplicationSchemaMessage remoteSchemaMessage =
                    x.ExchangeSchema(exchangeMessage);
                return new WcfReplicationSchema(remoteSchemaMessage);
            }, remoteNode.Host));
        }
Пример #2
0
        public WcfReplicationSchema(IReplicationSchema replicationSchema)
        {
            if (replicationSchema == null)
            {
                throw new ArgumentNullException("replicationSchema");
            }

            this.ReplicationSchema = replicationSchema;
        }
Пример #3
0
        /// <summary>
        /// Обновляет знания о существующей схеме репликации.
        /// </summary>
        /// <param name="remoteSchema">Схема репликации узла, с которого пришел запрос.</param>
        public IReplicationSchema UpdateReplicationSchema(IReplicationSchema remoteSchema)
        {
            //обновление локальной схемы
            this.ReplicationObserver.UpdateSchema(remoteSchema);

            //возврат текущей схемы
            IReplicationSchema currentSchema = this.ReplicationObserver.GetCurrentSchema();

            return(currentSchema);
        }
        public WcfReplicationSchemaMessage ExchangeSchema(WcfReplicationSchemaMessage remoteSchemaMessage)
        {
            if (remoteSchemaMessage == null)
            {
                throw new ArgumentNullException("remoteSchemaMessage");
            }

            WcfReplicationSchema        remoteSchema       = new WcfReplicationSchema(remoteSchemaMessage);
            IReplicationSchema          currentSchema      = this.ReplicationAdapter.UpdateReplicationSchema(remoteSchema);
            WcfReplicationSchema        typedCurrentSchema = new WcfReplicationSchema(currentSchema);
            WcfReplicationSchemaMessage responseMessage    = new WcfReplicationSchemaMessage(typedCurrentSchema);

            return(responseMessage);
        }
Пример #5
0
        private void GetNeighborsWorker(object state)
        {
            if (state == null)
            {
                throw new ArgumentNullException("state");
            }

            StorageNode node = (StorageNode)state;

            while (true)
            {
                try
                {
                    //периодически запрашиваем информацию о сети
                    //передаем текущие папки, которые реплицируются на данной ноде
                    //чтобы возвращать только пересекающиеся
                    IReplicationSchema currentSchema = this.GetCurrentSchema();
                    IReplicationSchema remoteSchema  = this.ReplicationAdapter.Transport.ExchangeSchema(node, currentSchema);

                    //обновляем схему по схеме соседнего узла по следующей логике
                    //что пришло со строгой ссылкой, то всегда создаем (значит эта настройка соседнего узла)
                    //со слабой ссылкой создаем только папки, по которым мы пересекаемся
                    if (remoteSchema != null)
                    {
                        this.UpdateSchema(remoteSchema);
                    }
                }
                catch (Exception ex)
                {
                    this.Engine.Logger.WriteMessage(ex.ToString());
                }
                finally
                {
                    Thread.Sleep(Timeouts.Schema);
                }
            }
        }
Пример #6
0
        private void UpdateSchemaItem(IReplicationSchema remoteSchema, IReplicationSchemaItem remoteSchemaItem)
        {
            if (remoteSchema == null)
            {
                throw new ArgumentNullException("remoteSchema");
            }

            if (remoteSchemaItem == null)
            {
                throw new ArgumentNullException("remoteSchemaItem");
            }

            bool forCurrentStorage = remoteSchemaItem.StorageID == this.Engine.CurrentNode.UniqueID;
            bool isStrongRelation  = remoteSchemaItem.RelationType == ReplicationRelation.Strong;

            //хост хранилища может поменяться
            //ищем по UniqueID и если не совпадают хосты, то меняем хост
            //доверяем хосту, только от которого пришел ответ
            if (forCurrentStorage)
            {
                if (isStrongRelation)
                {
                    //есть строгая ссылка на текущий узел, для узла, с которого пришел запрос.
                    #region Обновление информации об узле
                    bool        justCreated;
                    StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated);

                    if (!justCreated)
                    {
                        //если узел уже был, то проверяем нужно ли обновить хост существующего узла
                        if (remoteNode.Host.ToLower() != remoteSchema.Host.ToLower())
                        {
                            lock (_updateStorageLocker)
                            {
                                if (remoteNode.Host.ToLower() != remoteSchema.Host.ToLower())
                                {
                                    remoteNode.Host = remoteSchema.Host.ToLower();
                                    remoteNode.Update();
                                }
                            }
                        }
                    }
                    #endregion
                }
            }

            //если это STRONG признак, то создаем, если настройки нет
            foreach (string folderUrl in remoteSchemaItem.Folders)
            {
                if (isStrongRelation)
                {
                    #region strong relation
                    //настройка пришла непосредственно с узла схемы и на этом узле есть
                    //если она предназначена для текущего узла, то создаем/снимаем признак удаленности
                    if (forCurrentStorage)
                    {
                        //узел remote схемы
                        bool        justCreated;
                        StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated);

                        //получаем папку для репликации с remote узлом
                        bool replicationFolderJustCreated;
                        ReplicationFolder replicationFolder = this.EnsureReplicationFolder(remoteNode, folderUrl, false, out replicationFolderJustCreated);
                        if (!replicationFolderJustCreated)
                        {
                            //если настройка существовала и была удалена, то восстанавливаем ее
                            if (replicationFolder.Deleted)
                            {
                                replicationFolder.Deleted = false;
                                replicationFolder.Update();
                            }
                        }
                    }
                    else
                    {
                        //Strong ссылка на репликацию с 3-им (отличным от текущего) узлом,
                        //смотрим если на текущем узле есть пересекающиеся папки, то добавляем weak настройку
                        this.AddWeakRelation(remoteSchemaItem.StorageID, remoteSchemaItem.Name, folderUrl);
                    }
                    #endregion
                }
                else
                {
                    if (forCurrentStorage)
                    {
                        //слабые ссылки на самого себя не надо восстанавливать
                        continue;
                    }

                    //если это WEAK признак, то создаем, только если есть пересекающиеся настройки
                    this.AddWeakRelation(remoteSchemaItem.StorageID, remoteSchemaItem.Name, folderUrl);

                    //проверку на признак удаления делать не нужно, т.к. ссылка слабая
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Обновляет текущую схему репликацию сети, по схеме репликации другого узла сети.
        /// </summary>
        /// <param name="remoteSchema">Схема репликации другого узла сети.</param>
        internal void UpdateSchema(IReplicationSchema remoteSchema)
        {
            if (remoteSchema == null)
            {
                throw new ArgumentNullException("remoteSchema");
            }

            //remote схема содержит ссылки на текущий узел
            bool remoteSchemaContainsCurrentStorage = false;

            //обновляем схему по схеме соседнего узла по следующей логике
            //что пришло со строгой ссылкой, то всегда создаем (значит эта настройка соседнего узла)
            //со слабой ссылкой создаем только папки, по которым мы пересекаемся
            if (remoteSchema.StrongItems != null)
            {
                foreach (IReplicationSchemaItem schemaItem in remoteSchema.StrongItems)
                {
                    bool forCurrentStorage = schemaItem.StorageID == this.Engine.CurrentNode.UniqueID;
                    if (!remoteSchemaContainsCurrentStorage)
                    {
                        remoteSchemaContainsCurrentStorage = forCurrentStorage;
                    }

                    this.UpdateSchemaItem(remoteSchema, schemaItem);
                }
            }

            if (remoteSchema.WeakItems != null)
            {
                foreach (IReplicationSchemaItem schemaItem in remoteSchema.WeakItems)
                {
                    bool forCurrentStorage = schemaItem.StorageID == this.Engine.CurrentNode.UniqueID;
                    if (!remoteSchemaContainsCurrentStorage)
                    {
                        remoteSchemaContainsCurrentStorage = forCurrentStorage;
                    }

                    this.UpdateSchemaItem(remoteSchema, schemaItem);
                }
            }

            if (remoteSchemaContainsCurrentStorage)
            {
                //схема remote узла содержит текущий узел
                bool        justCreated;
                StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated);
                remoteNode.LastAccessTime = DateTime.Now;
                remoteNode.Update();
            }

            //удаление текущий настроек по remote схеме
            //для этого нужно пройтись по всем настройкам схемы текущего узла для remote узла
            if (_replicationFolders.ContainsKey(remoteSchema.StorageID))
            {
                #region Удаление из текущей схемы
                Dictionary <string, ReplicationFolder> replicationFoldersForRemoteSchema = _replicationFolders[remoteSchema.StorageID];
                foreach (ReplicationFolder replicationFolder in replicationFoldersForRemoteSchema.Values)
                {
                    if (replicationFolder.IsCurrentNodeSettings)
                    {
                        //в схеме текущего узла репликация с remote узлом задана в настройке (STRONG)
                        //такие настройки удалять не нужно
                        continue;
                    }

                    bool      containsInRemoteSchema = false;
                    FolderUri localUri = new FolderUri(replicationFolder.Folder.Url);

                    //содержаться может и в STRONG и в WEAK виде
                    if (remoteSchema.StrongItems != null)
                    {
                        foreach (IReplicationSchemaItem schemaItem in remoteSchema.StrongItems)
                        {
                            if (schemaItem.Folders != null)
                            {
                                foreach (string folderUrl in schemaItem.Folders)
                                {
                                    FolderUri remoteUri = new FolderUri(folderUrl);
                                    if (localUri.UrlLower == remoteUri.UrlLower)
                                    {
                                        containsInRemoteSchema = true;
                                        break;
                                    }
                                }
                            }

                            if (containsInRemoteSchema)
                            {
                                break;
                            }
                        }
                    }

                    if (!containsInRemoteSchema && remoteSchema.WeakItems != null)
                    {
                        foreach (IReplicationSchemaItem schemaItem in remoteSchema.WeakItems)
                        {
                            if (schemaItem.Folders != null)
                            {
                                foreach (string folderUrl in schemaItem.Folders)
                                {
                                    FolderUri remoteUri = new FolderUri(folderUrl);
                                    if (localUri.UrlLower == remoteUri.UrlLower)
                                    {
                                        containsInRemoteSchema = true;
                                        break;
                                    }
                                }
                            }

                            if (containsInRemoteSchema)
                            {
                                break;
                            }
                        }
                    }

                    //в remote схеме нет репликации с папками из схемы текущего узла
                    if (!containsInRemoteSchema)
                    {
                        replicationFolder.Deleted = true;
                        replicationFolder.Update();
                    }
                }
                #endregion
            }
        }