99using System . Diagnostics ;
1010using System . Linq ;
1111using System . Threading . Tasks ;
12+ using Autofac ;
13+ using Microsoft . Extensions . Configuration ;
14+ using Microsoft . Extensions . DependencyInjection ;
1215using Microsoft . Extensions . Logging ;
16+ using Microsoft . Extensions . Options ;
1317using NuGet . Jobs ;
14- using NuGet . Services . KeyVault ;
15- using NuGet . Services . Sql ;
18+ using NuGet . Jobs . Configuration ;
1619using IPackageIdGroup = System . Linq . IGrouping < string , Stats . AggregateCdnDownloadsInGallery . DownloadCountData > ;
1720
1821namespace Stats . AggregateCdnDownloadsInGallery
1922{
20- public class Job
21- : JobBase
23+ public class AggregateCdnDownloadsJob : JsonConfigurationJob
2224 {
2325 private const int _defaultBatchSize = 5000 ;
2426 private const int _defaultBatchSleepSeconds = 10 ;
@@ -55,40 +57,35 @@ GROUP BY Stats.[PackageRegistrationKey]
5557 DROP TABLE #AggregateCdnDownloadsInGallery" ;
5658
5759 private const string _storedProcedureName = "[dbo].[SelectTotalDownloadCountsPerPackageVersion]" ;
58- private ISqlConnectionFactory _statisticsDbConnectionFactory ;
59- private ISqlConnectionFactory _galleryDbConnectionFactory ;
60- private int _batchSize ;
61- private int _batchSleepSeconds ;
60+
61+ private AggregateCdnDownloadsConfiguration _configuration ;
6262
6363 public override void Init ( IServiceContainer serviceContainer , IDictionary < string , string > jobArgsDictionary )
6464 {
65- var secretInjector = ( ISecretInjector ) serviceContainer . GetService ( typeof ( ISecretInjector ) ) ;
66-
67- var statisticsDbConnectionString = JobConfigurationManager . GetArgument ( jobArgsDictionary , JobArgumentNames . StatisticsDatabase ) ;
68- _statisticsDbConnectionFactory = new AzureSqlConnectionFactory ( statisticsDbConnectionString , secretInjector ) ;
69-
70- var galleryDbConnectionString = JobConfigurationManager . GetArgument ( jobArgsDictionary , JobArgumentNames . DestinationDatabase ) ;
71- _galleryDbConnectionFactory = new AzureSqlConnectionFactory ( galleryDbConnectionString , secretInjector ) ;
65+ base . Init ( serviceContainer , jobArgsDictionary ) ;
7266
73- _batchSize = JobConfigurationManager . TryGetIntArgument ( jobArgsDictionary , JobArgumentNames . BatchSize ) ?? _defaultBatchSize ;
74- _batchSleepSeconds = JobConfigurationManager . TryGetIntArgument ( jobArgsDictionary , JobArgumentNames . BatchSleepSeconds ) ?? _defaultBatchSleepSeconds ;
67+ _configuration = _serviceProvider . GetRequiredService < IOptionsSnapshot < AggregateCdnDownloadsConfiguration > > ( ) . Value ;
7568 }
7669
7770 public override async Task Run ( )
7871 {
7972 // Gather download counts data from statistics warehouse
8073 IReadOnlyList < DownloadCountData > downloadData ;
81- Logger . LogInformation ( "Using batch size {BatchSize} and batch sleep seconds {BatchSleepSeconds}." , _batchSize , _batchSleepSeconds ) ;
82- Logger . LogInformation ( "Gathering Download Counts from {DataSource}/{InitialCatalog}..." , _statisticsDbConnectionFactory . DataSource , _statisticsDbConnectionFactory . InitialCatalog ) ;
74+ Logger . LogInformation ( "Using batch size {BatchSize} and batch sleep seconds {BatchSleepSeconds}." ,
75+ _configuration . BatchSize ,
76+ _configuration . BatchSleepSeconds ) ;
77+
8378 var stopwatch = Stopwatch . StartNew ( ) ;
8479
85- using ( var statisticsDatabase = await _statisticsDbConnectionFactory . CreateAsync ( ) )
86- using ( var statisticsDatabaseTransaction = statisticsDatabase . BeginTransaction ( IsolationLevel . Snapshot ) )
80+ using ( var connection = await OpenSqlConnectionAsync < StatisticsDbConfiguration > ( ) )
81+ using ( var transaction = connection . BeginTransaction ( IsolationLevel . Snapshot ) )
8782 {
83+ Logger . LogInformation ( "Gathering Download Counts from {DataSource}/{InitialCatalog}..." , connection . DataSource , connection . Database ) ;
84+
8885 downloadData = (
89- await statisticsDatabase . QueryWithRetryAsync < DownloadCountData > (
86+ await connection . QueryWithRetryAsync < DownloadCountData > (
9087 _storedProcedureName ,
91- transaction : statisticsDatabaseTransaction ,
88+ transaction : transaction ,
9289 commandType : CommandType . StoredProcedure ,
9390 commandTimeout : TimeSpan . FromMinutes ( 15 ) ,
9491 maxRetries : 3 ) )
@@ -106,10 +103,10 @@ await statisticsDatabase.QueryWithRetryAsync<DownloadCountData>(
106103 return ;
107104 }
108105
109- using ( var destinationDatabase = await _galleryDbConnectionFactory . CreateAsync ( ) )
106+ using ( var connection = await OpenSqlConnectionAsync < GalleryDbConfiguration > ( ) )
110107 {
111108 // Fetch package registrations so we can match package ID to package registration key.
112- var packageRegistrationLookup = await GetPackageRegistrations ( destinationDatabase ) ;
109+ var packageRegistrationLookup = await GetPackageRegistrations ( connection ) ;
113110
114111 // Group based on package ID and store in a stack for easy incremental processing.
115112 var allGroups = downloadData . GroupBy ( p => p . PackageId ) . ToList ( ) ;
@@ -126,18 +123,18 @@ await statisticsDatabase.QueryWithRetryAsync<DownloadCountData>(
126123 while ( remainingGroups . Any ( ) )
127124 {
128125 // Create a batch of one or more package registrations to update.
129- var batch = PopGroupBatch ( remainingGroups , _batchSize ) ;
126+ var batch = PopGroupBatch ( remainingGroups , _configuration . BatchSize ) ;
130127
131- await ProcessBatch ( batch , destinationDatabase , packageRegistrationLookup ) ;
128+ await ProcessBatch ( batch , connection , packageRegistrationLookup ) ;
132129
133130 Logger . LogInformation (
134131 "There are {GroupCount} package registration groups remaining." ,
135132 remainingGroups . Count ) ;
136133
137134 if ( remainingGroups . Any ( ) )
138135 {
139- Logger . LogInformation ( "Sleeping for {BatchSleepSeconds} seconds before continuing." , _batchSleepSeconds ) ;
140- await Task . Delay ( TimeSpan . FromSeconds ( _batchSleepSeconds ) ) ;
136+ Logger . LogInformation ( "Sleeping for {BatchSleepSeconds} seconds before continuing." , _configuration . BatchSleepSeconds ) ;
137+ await Task . Delay ( TimeSpan . FromSeconds ( _configuration . BatchSleepSeconds ) ) ;
141138 }
142139 }
143140
@@ -305,5 +302,14 @@ private async Task<IDictionary<string, string>> GetPackageRegistrations(SqlConne
305302
306303 return packageRegistrationDictionary ;
307304 }
305+
306+ protected override void ConfigureAutofacServices ( ContainerBuilder containerBuilder )
307+ {
308+ }
309+
310+ protected override void ConfigureJobServices ( IServiceCollection services , IConfigurationRoot configurationRoot )
311+ {
312+ ConfigureInitializationSection < AggregateCdnDownloadsConfiguration > ( services , configurationRoot ) ;
313+ }
308314 }
309315}
0 commit comments