Exemple #1
0
        public async Task DefineHub()
        {
            if (ResourceNameValidator.IsValidResourceName(Database.Name, ServerStore.Configuration.Core.DataDirectory.FullPath, out string errorMessage) == false)
            {
                throw new BadRequestException(errorMessage);
            }

            ServerStore.LicenseManager.AssertCanAddPullReplicationAsHub();

            PullReplicationDefinition pullReplication = null;

            await DatabaseConfigurations((_, databaseName, blittableJson, guid) =>
            {
                pullReplication = JsonDeserializationClient.PullReplicationDefinition(blittableJson);

                pullReplication.Validate(ServerStore.Server.Certificate?.Certificate != null);
                var updatePullReplication = new UpdatePullReplicationAsHubCommand(databaseName, guid)
                {
                    Definition = pullReplication
                };
                return(ServerStore.SendToLeaderAsync(updatePullReplication));
            }, "update-hub-pull-replication",
                                         GetRaftRequestIdFromQuery(),
                                         fillJson : (json, _, index) =>
            {
                json[nameof(OngoingTask.TaskId)] = pullReplication.TaskId == 0 ? index : pullReplication.TaskId;
            }, statusCode : HttpStatusCode.Created);
        }
        public override string UpdateDatabaseRecord(DatabaseRecord record, long etag)
        {
            if (Definition.TaskId == 0)
            {
                Definition.TaskId = etag;
            }
            else
            {
                PullReplicationDefinition.RemoveHub(record.HubPullReplications, Definition.TaskId);
            }

            record.EnsureTaskNameIsNotUsed(Definition.Name);
            record.HubPullReplications.Add(Definition);
            return(null);
        }
Exemple #3
0
        public async Task DisablePullReplicationOnHub()
        {
            DebuggerAttachedTimeout.DisableLongTimespan = true;

            var definitionName = $"pull-replication {GetDatabaseName()}";
            var timeout        = 10_000;

            using (var sink = GetDocumentStore())
                using (var hub = GetDocumentStore())
                {
                    var pullDefinition = new PullReplicationDefinition(definitionName);
                    var saveResult     = await hub.Maintenance.ForDatabase(hub.Database).SendAsync(new PutPullReplicationAsHubOperation(pullDefinition));

                    using (var main = hub.OpenSession())
                    {
                        main.Store(new User(), "users/1");
                        main.SaveChanges();
                    }
                    await SetupPullReplicationAsync(definitionName, sink, hub);

                    Assert.True(WaitForDocument(sink, "users/1", timeout), sink.Identifier);

                    var db = await Databases.GetDocumentDatabaseInstanceFor(sink);

                    var removedOnSink = new ManualResetEventSlim();
                    db.ReplicationLoader.IncomingReplicationRemoved += _ => removedOnSink.Set();

                    pullDefinition.Disabled = true;
                    pullDefinition.TaskId   = saveResult.TaskId;
                    await hub.Maintenance.ForDatabase(hub.Database).SendAsync(new PutPullReplicationAsHubOperation(pullDefinition));

                    Assert.True(removedOnSink.Wait(timeout));

                    using (var main = hub.OpenSession())
                    {
                        main.Store(new User(), "users/2");
                        main.SaveChanges();
                    }
                    Assert.False(WaitForDocument(sink, "users/2", timeout), sink.Identifier);

                    pullDefinition.Disabled = false;
                    pullDefinition.TaskId   = saveResult.TaskId;
                    await hub.Maintenance.ForDatabase(hub.Database).SendAsync(new PutPullReplicationAsHubOperation(pullDefinition));

                    Assert.True(WaitForDocument(sink, "users/2", timeout), sink.Identifier);
                }
        }
        private List <string> GetResponsibleNodes(DatabaseTopology topology, string databaseGroupId, PullReplicationDefinition pullReplication)
        {
            var list = new List <string>();
            // we distribute connections to have load balancing when many sinks are connected.
            // this is the hub cluster, so we make the decision which node will do the pull replication only once and only here,
            // for that we create a dummy IDatabaseTask.
            var mentorNodeTask = new PullNodeTask
            {
                Mentor          = pullReplication.MentorNode,
                DatabaseGroupId = databaseGroupId
            };

            while (topology.Members.Count > 0)
            {
                var next = topology.WhoseTaskIsIt(ServerStore.CurrentRachisState, mentorNodeTask, null);
                list.Add(next);
                topology.Members.Remove(next);
            }

            return(list);
        }