Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.
/ NuGet.Jobs Public archive

Migrate job to JsonConfig #550

Merged
merged 2 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace NuGet.Jobs.Configuration
{
public class SupportRequestDbConfiguration : IDbConfiguration
{
public string ConnectionString { get; set; }
}
}
56 changes: 25 additions & 31 deletions src/NuGet.Jobs.Common/JsonConfigurationJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public abstract class JsonConfigurationJob : JobBase
private const string InitializationConfigurationSectionName = "Initialization";
private const string GalleryDbConfigurationSectionName = "GalleryDb";
private const string StatisticsDbConfigurationSectionName = "StatisticsDb";
private const string SupportRequestDbConfigurationSectionName = "SupportRequestDb";
private const string ValidationDbConfigurationSectionName = "ValidationDb";
private const string ServiceBusConfigurationSectionName = "ServiceBus";
private const string ValidationStorageConfigurationSectionName = "ValidationStorage";
Expand Down Expand Up @@ -111,32 +112,28 @@ protected virtual void ConfigureDefaultJobServices(IServiceCollection services,
{
services.Configure<GalleryDbConfiguration>(configurationRoot.GetSection(GalleryDbConfigurationSectionName));
services.Configure<StatisticsDbConfiguration>(configurationRoot.GetSection(StatisticsDbConfigurationSectionName));
services.Configure<SupportRequestDbConfiguration>(configurationRoot.GetSection(SupportRequestDbConfigurationSectionName));
services.Configure<ValidationDbConfiguration>(configurationRoot.GetSection(ValidationDbConfigurationSectionName));
services.Configure<ServiceBusConfiguration>(configurationRoot.GetSection(ServiceBusConfigurationSectionName));
services.Configure<ValidationStorageConfiguration>(configurationRoot.GetSection(ValidationStorageConfigurationSectionName));

services.AddSingleton(new TelemetryClient());
services.AddTransient<ITelemetryClient, TelemetryClientWrapper>();

services.AddScoped<ISqlConnectionFactory<GalleryDbConfiguration>>(p =>
{
return new DelegateSqlConnectionFactory<GalleryDbConfiguration>(
CreateSqlConnectionAsync<GalleryDbConfiguration>,
p.GetRequiredService<ILogger<DelegateSqlConnectionFactory<GalleryDbConfiguration>>>());
});

services.AddScoped<ISqlConnectionFactory<StatisticsDbConfiguration>>(p =>
{
return new DelegateSqlConnectionFactory<StatisticsDbConfiguration>(
CreateSqlConnectionAsync<StatisticsDbConfiguration>,
p.GetRequiredService<ILogger<DelegateSqlConnectionFactory<StatisticsDbConfiguration>>>());
});
AddScopedSqlConnectionFactory<GalleryDbConfiguration>(services);
AddScopedSqlConnectionFactory<StatisticsDbConfiguration>(services);
AddScopedSqlConnectionFactory<SupportRequestDbConfiguration>(services);
AddScopedSqlConnectionFactory<ValidationDbConfiguration>(services);
}

services.AddScoped<ISqlConnectionFactory<ValidationDbConfiguration>>(p =>
private void AddScopedSqlConnectionFactory<TDbConfiguration>(IServiceCollection services)
where TDbConfiguration : IDbConfiguration
{
services.AddScoped<ISqlConnectionFactory<TDbConfiguration>>(p =>
{
return new DelegateSqlConnectionFactory<ValidationDbConfiguration>(
CreateSqlConnectionAsync<ValidationDbConfiguration>,
p.GetRequiredService<ILogger<DelegateSqlConnectionFactory<ValidationDbConfiguration>>>());
return new DelegateSqlConnectionFactory<TDbConfiguration>(
CreateSqlConnectionAsync<TDbConfiguration>,
p.GetRequiredService<ILogger<DelegateSqlConnectionFactory<TDbConfiguration>>>());
});
}

Expand All @@ -150,22 +147,19 @@ private void ConfigureLibraries(IServiceCollection services)

protected virtual void RegisterDatabases(IServiceProvider serviceProvider)
{
var galleryDb = serviceProvider.GetRequiredService<IOptionsSnapshot<GalleryDbConfiguration>>();
if (!string.IsNullOrEmpty(galleryDb.Value?.ConnectionString))
{
RegisterDatabase<GalleryDbConfiguration>(serviceProvider);
}

var statisticsDb = serviceProvider.GetRequiredService<IOptionsSnapshot<StatisticsDbConfiguration>>();
if (!string.IsNullOrEmpty(statisticsDb.Value?.ConnectionString))
{
RegisterDatabase<StatisticsDbConfiguration>(serviceProvider);
}
RegisterDatabaseIfConfigured<GalleryDbConfiguration>(serviceProvider);
RegisterDatabaseIfConfigured<StatisticsDbConfiguration>(serviceProvider);
RegisterDatabaseIfConfigured<SupportRequestDbConfiguration>(serviceProvider);
RegisterDatabaseIfConfigured<ValidationDbConfiguration>(serviceProvider);
}

var validationDb = serviceProvider.GetRequiredService<IOptionsSnapshot<ValidationDbConfiguration>>();
if (!string.IsNullOrEmpty(validationDb.Value?.ConnectionString))
private void RegisterDatabaseIfConfigured<TDbConfiguration>(IServiceProvider serviceProvider)
where TDbConfiguration : IDbConfiguration
{
var dbConfiguration = serviceProvider.GetRequiredService<IOptionsSnapshot<TDbConfiguration>>();
if (!string.IsNullOrEmpty(dbConfiguration.Value?.ConnectionString))
{
RegisterDatabase<ValidationDbConfiguration>(serviceProvider);
RegisterDatabase<TDbConfiguration>(serviceProvider);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/NuGet.Jobs.Common/NuGet.Jobs.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<Compile Include="Configuration\JobArgumentNames.cs" />
<Compile Include="Configuration\ServiceBusConfiguration.cs" />
<Compile Include="Configuration\StatisticsDbConfiguration.cs" />
<Compile Include="Configuration\SupportRequestDbConfiguration.cs" />
<Compile Include="Configuration\ValidationDbConfiguration.cs" />
<Compile Include="Configuration\ValidationStorageConfiguration.cs" />
<Compile Include="DelegateSqlConnectionFactory.cs" />
Expand Down Expand Up @@ -93,13 +94,13 @@
<Version>2.27.0</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.KeyVault">
<Version>2.27.0</Version>
<Version>2.28.0</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.Logging">
<Version>2.27.0</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.Sql">
<Version>2.27.0</Version>
<Version>2.28.0</Version>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing warnings due to partial dependencies upgrade in a previous PR. KeyVault and Sql libraries had been updated to 2.28.0 for Validation.Common.Job, but not Jobs.Common.

https://github.com/NuGet/NuGet.Jobs/blame/master/src/Validation.Common.Job/Validation.Common.Job.csproj#L106

</PackageReference>
<PackageReference Include="System.Net.Http">
<Version>4.3.3</Version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@
<PackageReference Include="AnglicanGeek.MarkdownMailer.StrongName">
<Version>1.2.0</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.Sql">
<Version>2.27.0</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.Validation.Issues">
<Version>2.27.0-master-35351</Version>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace NuGet.SupportRequests.Notifications
{
public class InitializationConfiguration
{
/// <summary>
/// Obsolete: replace with IcM configuration
/// </summary>
public string PagerDutyAccountName { get; set; }

/// <summary>
/// Obsolete: replace with IcM configuration
/// </summary>
public string PagerDutyApiKey { get; set; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code still uses PagerDuty. I can remove in follow-up PR, if it's not too time consuming.


/// <summary>
/// SMTP configuration.
/// </summary>
public string SmtpUri { get; set; }

/// <summary>
/// Email address to which the weekly report is sent.
/// </summary>
public string TargetEmailAddress { get; set; }
}
}
36 changes: 25 additions & 11 deletions src/NuGet.SupportRequests.Notifications/Job.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Threading.Tasks;
using Autofac;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NuGet.Jobs;
using NuGet.Jobs.Configuration;

namespace NuGet.SupportRequests.Notifications
{
internal class Job
: JobBase
: JsonConfigurationJob
{
private IServiceContainer _serviceContainer;
private IDictionary<string, string> _jobArgsDictionary;
private InitializationConfiguration _configuration;
private string _taskName;

public override void Init(IServiceContainer serviceContainer, IDictionary<string, string> jobArgsDictionary)
{
if (!jobArgsDictionary.ContainsKey(JobArgumentNames.ScheduledTask))
{
throw new NotSupportedException("The required argument -Task is missing.");
}
base.Init(serviceContainer, jobArgsDictionary);

_serviceContainer = serviceContainer ?? throw new ArgumentNullException(nameof(serviceContainer));
_jobArgsDictionary = jobArgsDictionary;
_taskName = jobArgsDictionary[JobArgumentNames.ScheduledTask];
_configuration = _serviceProvider.GetRequiredService<IOptionsSnapshot<InitializationConfiguration>>().Value;
}

public override async Task Run()
{
var scheduledTask = ScheduledTaskFactory.Create(_serviceContainer, _jobArgsDictionary, LoggerFactory);
var scheduledTask = ScheduledTaskFactory.Create(
_taskName,
_configuration,
OpenSqlConnectionAsync<SupportRequestDbConfiguration>,
LoggerFactory);

await scheduledTask.RunAsync();
}

protected override void ConfigureAutofacServices(ContainerBuilder containerBuilder)
{
}

protected override void ConfigureJobServices(IServiceCollection services, IConfigurationRoot configurationRoot)
{
ConfigureInitializationSection<InitializationConfiguration>(services, configurationRoot);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\InitializationConfiguration.cs" />
<Compile Include="Images.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
Expand Down Expand Up @@ -95,20 +96,17 @@
</None>
<None Include="Scripts\*" />
<None Include="NuGet.SupportRequests.Notifications.nuspec" />
<None Include="Settings\dev.json" />
<None Include="Settings\int.json" />
<None Include="Settings\prod.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>9.0.1</Version>
</PackageReference>
<PackageReference Include="NuGet.Services.Sql">
<Version>2.27.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\sign.targets" Condition="Exists('..\..\build\sign.targets')" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@

<file src="Scripts\OnCallDailyNotification.cmd" />
<file src="Scripts\WeeklySummaryNotification.cmd" />

<file src="Settings\*.json" target="bin" />
</files>
</package>
32 changes: 22 additions & 10 deletions src/NuGet.SupportRequests.Notifications/ScheduledTaskFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace NuGet.SupportRequests.Notifications
Expand All @@ -12,28 +12,35 @@ internal class ScheduledTaskFactory
{
private const string _tasksNamespace = "NuGet.SupportRequests.Notifications.Tasks";

public static IScheduledTask Create(IServiceContainer serviceContainer, IDictionary<string, string> jobArgsDictionary, ILoggerFactory loggerFactory)
public static IScheduledTask Create(
string scheduledTaskName,
InitializationConfiguration configuration,
Func<Task<SqlConnection>> openSupportRequestSqlConnectionAsync,
ILoggerFactory loggerFactory)
{
if (jobArgsDictionary == null)
if (configuration == null)
{
throw new ArgumentNullException(nameof(jobArgsDictionary));
throw new ArgumentNullException(nameof(configuration));
}

if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}

var scheduledTaskName = jobArgsDictionary[JobArgumentNames.ScheduledTask];
var scheduledTask = GetTaskOfType(scheduledTaskName, serviceContainer, jobArgsDictionary, loggerFactory);
var scheduledTask = GetTaskOfType(
scheduledTaskName,
configuration,
openSupportRequestSqlConnectionAsync,
loggerFactory);

return scheduledTask;
}

private static IScheduledTask GetTaskOfType(
string taskName,
IServiceContainer serviceContainer,
IDictionary<string, string> jobArgsDictionary,
InitializationConfiguration configuration,
Func<Task<SqlConnection>> openSupportRequestSqlConnectionAsync,
ILoggerFactory loggerFactory)
{
if (string.IsNullOrEmpty(taskName))
Expand All @@ -51,7 +58,12 @@ private static IScheduledTask GetTaskOfType(
IScheduledTask scheduledTask;
if (scheduledTaskType != null && typeof(IScheduledTask).IsAssignableFrom(scheduledTaskType))
{
var args = new object[] { serviceContainer, jobArgsDictionary, loggerFactory };
var args = new object[] {
configuration,
openSupportRequestSqlConnectionAsync,
loggerFactory
};

scheduledTask = (IScheduledTask)Activator.CreateInstance(scheduledTaskType, args);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@ echo "Starting job - NuGet - SupportRequests.Notifications.OnCallDailyNotificati
title "NuGet - SupportRequests.Notifications.OnCallDailyNotification.cmd"

start /w nuget.supportrequests.notifications.exe ^
-Task "OnCallDailyNotification" ^
-SourceDatabase "#{Jobs.supportrequests.notifications.SupportRequestsDatabase}" ^
-PagerDutyAccountName "nuget" ^
-PagerDutyApiKey "$$Prod-PagerDuty-ApiKey$$" ^
-SmtpUri "#{Jobs.supportrequests.notifications.SmtpUri}" ^
-VaultName "#{Deployment.Azure.KeyVault.VaultName}" ^
-ClientId "#{Deployment.Azure.KeyVault.ClientId}" ^
-CertificateThumbprint "#{Deployment.Azure.KeyVault.CertificateThumbprint}" ^
-InstrumentationKey "#{Jobs.supportrequests.notifications.InstrumentationKey}" ^
-verbose true ^
-Once
-Task "OnCallDailyNotification" ^
-Configuration "#{Jobs.supportrequests.notifications.Configuration}" ^
-InstrumentationKey "#{Jobs.supportrequests.notifications.InstrumentationKey}" ^
-verbose true ^
-Once

echo "Finished job - NuGet - SupportRequests.Notifications.OnCallDailyNotification.cmd"
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ title "NuGet - SupportRequests.Notifications.WeeklySummaryNotification.cmd"

start /w nuget.supportrequests.notifications.exe ^
-Task "WeeklySummaryNotification" ^
-TargetEmailAddress "#{Jobs.supportrequests.notifications.weeklysummarynotification.TargetEmailAddress}" ^
-SourceDatabase "#{Jobs.supportrequests.notifications.SupportRequestsDatabase}" ^
-PagerDutyAccountName "nuget" ^
-PagerDutyApiKey "$$Prod-PagerDuty-ApiKey$$" ^
-SmtpUri "#{Jobs.supportrequests.notifications.SmtpUri}" ^
-VaultName "#{Deployment.Azure.KeyVault.VaultName}" ^
-ClientId "#{Deployment.Azure.KeyVault.ClientId}" ^
-CertificateThumbprint "#{Deployment.Azure.KeyVault.CertificateThumbprint}" ^
-Configuration "#{Jobs.supportrequests.notifications.Configuration}" ^
-InstrumentationKey "#{Jobs.supportrequests.notifications.InstrumentationKey}" ^
-verbose true ^
-Once
Expand Down
19 changes: 19 additions & 0 deletions src/NuGet.SupportRequests.Notifications/Settings/dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Initialization": {
"PagerDutyAccountName": "nuget",
"PagerDutyApiKey": "$$Dev-PagerDuty-ApiKey$$",
"SmtpUri": "#{Jobs.supportrequests.notifications.SmtpUri}",
"TargetEmailAddress": "#{Jobs.supportrequests.notifications.weeklysummarynotification.TargetEmailAddress}"
},

"SupportRequestDb": {
"ConnectionString": "Data Source=tcp:#{Deployment.Azure.Sql.SupportRequestDatabaseAddress};Initial Catalog=nuget-dev-supportrequest;User ID=$$Dev-SupportRequestDBWriter-UserName$$;Password=$$Dev-SupportRequestDBWriter-Password$$;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: we don't have DEV/INT enabled on Octopus, but I'm adding config in case we want to enable or to ease testing.

I didn't want to add new DB creds to KeyVault, so these reference the existing writer credentials. This will change when AAD is configured.

},

"KeyVault_VaultName": "#{Deployment.Azure.KeyVault.VaultName}",
"KeyVault_ClientId": "#{Deployment.Azure.KeyVault.ClientId}",
"KeyVault_CertificateThumbprint": "#{Deployment.Azure.KeyVault.CertificateThumbprint}",
"KeyVault_ValidateCertificate": true,
"KeyVault_StoreName": "My",
"KeyVault_StoreLocation": "LocalMachine"
}
Loading