private string FetchTargetServerUrl(ReplicationDestination replicationDestination) { var url = $"{replicationDestination.Url}/debug/config"; try { var replicationStrategy = ReplicationTask.GetConnectionOptions(replicationDestination, database); var request = requestFactory.Create(url, HttpMethods.Get, replicationStrategy.ConnectionStringOptions); var ravenConfig = request.ExecuteRequest <RavenJObject>(); var serverUrlFromTargetConfig = ravenConfig.Value <string>("ServerUrl"); // replace host name with target hostname return(new UriBuilder(replicationDestination.Url) { Host = new Uri(serverUrlFromTargetConfig).Host }.Uri.ToString()); } catch (Exception e) { if (replicationDestination.Url.EndsWith("/")) { return(replicationDestination.Url); } return(replicationDestination.Url + "/"); } }
public DocumentCount Calculate(ServerInfo serverInfo) { var replicationDocument = GetReplicationDocument(); if (serverInfo.SourceId != DatabaseId) { return(GetDocumentsLeftCountFromAnotherSourceServer(replicationDocument, serverInfo)); } var replicationDestination = replicationDocument .Destinations .FirstOrDefault(x => FetchTargetServerUrl(x).Equals(serverInfo.DestinationUrl, StringComparison.CurrentCultureIgnoreCase) && x.Database.Equals(serverInfo.DatabaseName, StringComparison.CurrentCultureIgnoreCase)); if (replicationDestination == null) { throw new InvalidOperationException($"Couldn't find replication destination for url: {serverInfo.DestinationUrl} and database: {serverInfo.DatabaseName}"); } var replicationStrategy = ReplicationTask.GetConnectionOptions(replicationDestination, database); if (replicationStrategy.IsETL == false) { return(GetDocumentsLeftCount(replicationStrategy, serverInfo.DestinationUrl, serverInfo.DatabaseName)); } return(GetDocumentsLeftCountForEtl(replicationStrategy, serverInfo.DestinationUrl, serverInfo.DatabaseName)); }
private DocumentCount DocumentsLeftCountFromAnotherSourceServer(ServerInfo serverInfo, ReplicationDestination.ReplicationDestinationWithConfigurationOrigin replicationDestination) { var replicationStrategy = ReplicationTask.GetConnectionOptions(replicationDestination, database); var url = $"{replicationStrategy.ConnectionStringOptions.Url}/admin/replication/docs-left-to-replicate"; var request = requestFactory.Create(url, HttpMethods.Post, replicationStrategy.ConnectionStringOptions); request.Write(RavenJObject.FromObject(serverInfo)); var documentsLeftCount = request.ExecuteRequest <DocumentCount>(); return(documentsLeftCount); }
private ReplicationTopologyDestinationNode HandleDestination(ReplicationDestination replicationDestination) { var destination = ReplicationTask.GetConnectionOptions(replicationDestination, database); if (replicationDestination.Disabled) { return(ReplicationTopologyDestinationNode.Disabled(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); } if (from.Contains(destination.ConnectionStringOptions.Url)) { var state = CheckDestinationConnectionState(destination); switch (state) { case ReplicatonNodeState.Online: return(ReplicationTopologyDestinationNode.Online(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); case ReplicatonNodeState.Offline: return(ReplicationTopologyDestinationNode.Offline(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); default: throw new NotSupportedException(state.ToString()); } } string error; ReplicationTopologyRootNode rootNode; if (TryGetSchema(destination.ConnectionStringOptions.Url, destination.ConnectionStringOptions, out rootNode, out error)) { var node = ReplicationTopologyDestinationNode.Online(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior); node.Destinations = rootNode.Destinations; node.Sources = rootNode.Sources; node.Errors = rootNode.Errors; return(node); } var offline = ReplicationTopologyDestinationNode.Offline(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior); if (string.IsNullOrEmpty(error) == false) { offline.Errors.Add(error); } return(offline); }
public void ExtractDocumentIds(ServerInfo serverInfo, Action <string> successAction, Action skippedAction) { var replicationDocument = GetReplicationDocument(); var replicationDestination = replicationDocument .Destinations .FirstOrDefault(x => FetchTargetServerUrl(x).Equals(serverInfo.DestinationUrl, StringComparison.CurrentCultureIgnoreCase) && x.Database.Equals(serverInfo.DatabaseName, StringComparison.CurrentCultureIgnoreCase)); if (replicationDestination == null) { throw new InvalidOperationException($"Couldn't find replication destination for url: {serverInfo.DestinationUrl} and database: {serverInfo.DatabaseName}"); } var replicationStrategy = ReplicationTask.GetConnectionOptions(replicationDestination, database); var sourcesDocument = replicationTask.GetLastReplicatedEtagFrom(replicationStrategy); if (sourcesDocument == null) { throw new InvalidOperationException($"Couldn't get last replicated etag for " + $"destination url: {serverInfo.DestinationUrl} and database: {serverInfo.DatabaseName}"); } database.TransactionalStorage.Batch(actions => { var earlyExit = new Reference <bool>(); //get document count since last replicated etag var documentIds = actions.Documents.GetDocumentIdsAfterEtag( sourcesDocument.LastDocumentEtag, int.MaxValue, WillDocumentBeReplicated(replicationStrategy, sourcesDocument.ServerInstanceId.ToString(), skippedAction), earlyExit, database.WorkContext.CancellationToken); foreach (var documentId in documentIds) { successAction(documentId); } }); }
private ReplicationTopologyDestinationNode HandleDestination(ReplicationDestination replicationDestination) { var destination = ReplicationTask.GetConnectionOptions(replicationDestination, database); string error; string targetServerUrl; // since each server can be addresses using both dns and ips we normalize connection string url by fetching target server url // it should give us consistent urls if (FetchTargetServerUrl(destination.ConnectionStringOptions.Url, destination.ConnectionStringOptions, out targetServerUrl, out error) == false) { var offlineNode = ReplicationTopologyDestinationNode.Offline(destination.ConnectionStringOptions.Url, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior); if (string.IsNullOrEmpty(error) == false) { offlineNode.Errors.Add(error); } return(offlineNode); } if (replicationDestination.Disabled) { return(ReplicationTopologyDestinationNode.Disabled(targetServerUrl, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); } if (from.Contains(targetServerUrl)) { var state = CheckDestinationConnectionState(destination); switch (state) { case ReplicatonNodeState.Online: return(ReplicationTopologyDestinationNode.Online(targetServerUrl, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); case ReplicatonNodeState.Offline: return(ReplicationTopologyDestinationNode.Offline(targetServerUrl, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior)); default: throw new NotSupportedException(state.ToString()); } } ReplicationTopologyRootNode rootNode; if (TryGetSchema(destination.ConnectionStringOptions.Url, destination.ConnectionStringOptions, out rootNode, out error)) { var node = ReplicationTopologyDestinationNode.Online(targetServerUrl, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior); node.Destinations = rootNode.Destinations; node.Sources = rootNode.Sources; node.Errors = rootNode.Errors; return(node); } var offline = ReplicationTopologyDestinationNode.Offline(targetServerUrl, database.TransactionalStorage.Id, destination.ReplicationOptionsBehavior); if (string.IsNullOrEmpty(error) == false) { offline.Errors.Add(error); } return(offline); }