public async Task Between(SmugglerBetweenOptions <CounterConnectionStringOptions> betweenOptions) { if (betweenOptions.ReportProgress == null) { betweenOptions.ReportProgress = msg => { } } ; using (var source = new CounterStore { Url = betweenOptions.From.Url, Name = betweenOptions.From.CounterStoreId, Credentials = new OperationCredentials(betweenOptions.From.ApiKey, betweenOptions.From.Credentials) }) using (var target = new CounterStore { Url = betweenOptions.To.Url, Name = betweenOptions.To.CounterStoreId, Credentials = new OperationCredentials(betweenOptions.To.ApiKey, betweenOptions.To.Credentials) }) { source.Initialize(true); ShowProgress($"Initialized connection to source counter store (name = {source.Name})"); target.Initialize(true); ShowProgress($"Initialized connection to target counter store (name = {target.Name})"); var existingCounterGroupsAndNames = await target.Admin.GetCounterStorageNameAndGroups(token : CancellationToken).ConfigureAwait(false); var counterSummaries = await source.Advanced.GetCounters(token : CancellationToken).ConfigureAwait(false); ShowProgress($"Fetched counter data from source (there is data about {counterSummaries.Count} counters)"); foreach (var summary in counterSummaries) { if (existingCounterGroupsAndNames.Any(x => x.Group == summary.GroupName && x.Name == summary.CounterName)) { ShowProgress($"Counter {summary.GroupName} - {summary.CounterName} is already there. Reset is performed"); await target.ResetAsync(summary.GroupName, summary.CounterName, CancellationToken) .WithCancellation(CancellationToken) .ConfigureAwait(false); //since it is a full import, the values are overwritten } ShowProgress($"Importing counter {summary.GroupName} - {summary.CounterName}"); target.Batch.ScheduleChange(summary.GroupName, summary.CounterName, summary.Total); } ShowProgress("Finished import..."); await target.Batch.FlushAsync().WithCancellation(CancellationToken).ConfigureAwait(false); } } }
//assumes that the caller has responsibility to handle data stream disposal ("stream" parameter) private async Task ImportFullData(CounterConnectionStringOptions connectionString, Stream stream) { CountingStream sizeStream; JsonTextReader jsonReader; if (SmugglerHelper.TryGetJsonReaderForStream(stream, out jsonReader, out sizeStream) == false) { throw new InvalidOperationException("Failed to get reader for the data stream."); } if (jsonReader.TokenType != JsonToken.StartObject) { throw new InvalidDataException("StartObject was expected"); } ICounterStore store = null; try { if (jsonReader.Read() == false && jsonReader.TokenType != JsonToken.StartArray) { throw new InvalidDataException("StartArray was expected"); } store = new CounterStore { Url = connectionString.Url, Name = connectionString.CounterStoreId, Credentials = new OperationCredentials(connectionString.ApiKey, connectionString.Credentials) }; store.Initialize(true); ShowProgress($"Initialized connection to counter store (name = {store.Name})"); var existingCounterGroupsAndNames = await store.Admin.GetCounterStorageNameAndGroups(token : CancellationToken) .WithCancellation(CancellationToken) .ConfigureAwait(false); while (jsonReader.Read() && jsonReader.TokenType != JsonToken.EndArray) { if (jsonReader.TokenType != JsonToken.StartObject) { continue; } var counterInfo = (RavenJObject)RavenJToken.ReadFrom(jsonReader); var delta = Math.Abs(counterInfo.Value <long>("Positive")) - Math.Abs(counterInfo.Value <long>("Negative")); var groupName = counterInfo.Value <string>("Group"); var counterName = counterInfo.Value <string>("Name"); if (existingCounterGroupsAndNames.Any(x => x.Group == groupName && x.Name == counterName)) { ShowProgress($"Counter {groupName} - {counterName} is already there. Reset is performed"); await store.ResetAsync(groupName, counterName, CancellationToken).ConfigureAwait(false); //since it is a full import, the values are overwritten } ShowProgress($"Importing counter {groupName} - {counterName}"); store.Batch.ScheduleChange(groupName, counterName, delta); } ShowProgress("Finished import..."); await store.Batch.FlushAsync().WithCancellation(CancellationToken).ConfigureAwait(false); } finally { store?.Dispose(); } }