Introducing new interfaces to clean up ScaleHost DI model
This commit is contained in:
Родитель
1768447932
Коммит
963a7f6262
|
@ -15,5 +15,6 @@ namespace Microsoft.Azure.WebJobs.Host
|
|||
public const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
|
||||
public const string AzureWebsiteContainerName = "CONTAINER_NAME";
|
||||
public const string DateTimeFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK";
|
||||
public const string ScaleHostEnvironmentSettingName = "IsAzureWebJobsScaleHost";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Azure.WebJobs.Host.Scale;
|
||||
|
||||
namespace Microsoft.Azure.WebJobs.Host.Hosting
|
||||
{
|
||||
/// <summary>
|
||||
/// Context containing triggers metadata needed to be confiured for scale in an extension.
|
||||
/// </summary>
|
||||
public class ScaleHostBuilderContext : WebJobsBuilderContext
|
||||
{
|
||||
private IEnumerable<TriggerMetadata> _triggersMetadata;
|
||||
|
||||
public ScaleHostBuilderContext(IEnumerable<TriggerMetadata> triggersMetadata)
|
||||
{
|
||||
_triggersMetadata = triggersMetadata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see cref="IEnumerable"> of <see cref="TriggerMetadata"/> by trigger type.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<TriggerMetadata> GetTriggersMetadata(string type) => _triggersMetadata.Where(x => x.Type == type);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Microsoft.Azure.WebJobs
|
||||
|
@ -10,6 +12,11 @@ namespace Microsoft.Azure.WebJobs
|
|||
/// </summary>
|
||||
public class WebJobsBuilderContext
|
||||
{
|
||||
public WebJobsBuilderContext()
|
||||
{
|
||||
Properties = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IConfiguration"/> containing the merged configuration of the application and the host.
|
||||
/// </summary>
|
||||
|
@ -24,5 +31,10 @@ namespace Microsoft.Azure.WebJobs
|
|||
/// Gets or sets the absolute path to the directory that contains the application content files.
|
||||
/// </summary>
|
||||
public string ApplicationRootPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A central location for sharing state between components during the host building process.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Properties { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Azure.WebJobs.Host.Scale
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider interface for returning a collection of <see cref="IScaleMonitor"/> instances.
|
||||
/// </summary>
|
||||
public interface IScaleMonitorCollectionProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection of <see cref="IScaleMonitor"/> instances.
|
||||
/// </summary>
|
||||
/// <returns>The collection of <see cref="IScaleMonitor"/> instances.</returns>
|
||||
IEnumerable<IScaleMonitor> GetScaleMonitors();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Azure.WebJobs.Host.Scale
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider interface for returning a collection of <see cref="ITargetScaler"/> instances.
|
||||
/// </summary>
|
||||
public interface ITargetScalerCollectionProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection of <see cref="ITargetScaler"/> instances.
|
||||
/// </summary>
|
||||
/// <returns>The collection of <see cref="ITargetScaler"/> instances.</returns>
|
||||
IEnumerable<ITargetScaler> GetTargetScalers();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Azure.WebJobs.Host.Scale
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider interface for returning a collection of <see cref="TriggerMetadata"/> instances.
|
||||
/// </summary>
|
||||
public interface ITriggerMetadataProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection of <see cref="TriggerMetadata"/> instances.
|
||||
/// </summary>
|
||||
/// <returns>The collection of <see cref="TriggerMetadata"/> instances.</returns>
|
||||
public IEnumerable<TriggerMetadata> GetTriggerMetadata();
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Host.Scale
|
|||
{
|
||||
}
|
||||
|
||||
public ScaleMonitorManager(IEnumerable<IScaleMonitor> monitors, IEnumerable<IScaleMonitorProvider> monitorProviders)
|
||||
public ScaleMonitorManager(IEnumerable<IScaleMonitor> monitors, IEnumerable<IScaleMonitorProvider> monitorProviders, IEnumerable<IScaleMonitorCollectionProvider> monitorCollectionProviders)
|
||||
{
|
||||
// add any initial monitors coming from DI
|
||||
// additional monitors can be added at runtime
|
||||
|
@ -24,6 +24,9 @@ namespace Microsoft.Azure.WebJobs.Host.Scale
|
|||
|
||||
// add monitors coming from any registered providers
|
||||
_monitors.AddRange(monitorProviders.Select(p => p.GetMonitor()));
|
||||
|
||||
// add monitors coming from any registered collection providers
|
||||
_monitors.AddRange(monitorCollectionProviders.SelectMany(p => p.GetScaleMonitors()));
|
||||
}
|
||||
|
||||
public void Register(IScaleMonitor monitor)
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Host.Scale
|
|||
{
|
||||
}
|
||||
|
||||
public TargetScalerManager(IEnumerable<ITargetScaler> targetScalers, IEnumerable<ITargetScalerProvider> scalerProviders)
|
||||
public TargetScalerManager(IEnumerable<ITargetScaler> targetScalers, IEnumerable<ITargetScalerProvider> scalerProviders, IEnumerable<ITargetScalerCollectionProvider> scalerCollectionProvider)
|
||||
{
|
||||
// add any initial target scalers coming from DI
|
||||
// additional monitors can be added at runtime
|
||||
|
@ -24,6 +24,9 @@ namespace Microsoft.Azure.WebJobs.Host.Scale
|
|||
|
||||
// add scalers coming from any registered providers
|
||||
_targetScalers.AddRange(scalerProviders.Select(p => p.GetTargetScaler()));
|
||||
|
||||
// add scalers coming from any registered collection providers
|
||||
_targetScalers.AddRange(scalerCollectionProvider.SelectMany(p => p.GetTargetScalers()));
|
||||
}
|
||||
|
||||
public void Register(ITargetScaler targetScaler)
|
||||
|
|
|
@ -10,7 +10,6 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale;
|
||||
using Microsoft.Azure.WebJobs.Host.Hosting;
|
||||
using Microsoft.Azure.WebJobs.Host.Scale;
|
||||
using Microsoft.Azure.WebJobs.Host.TestCommon;
|
||||
using Microsoft.Azure.WebJobs.Hosting;
|
||||
|
@ -25,8 +24,8 @@ using Newtonsoft.Json.Linq;
|
|||
using Xunit;
|
||||
using static Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale.ScaleHostEndToEndTests;
|
||||
|
||||
[assembly: WebJobsStartup(typeof(TestExtensionA))]
|
||||
[assembly: WebJobsStartup(typeof(TestExtensionB))]
|
||||
[assembly: WebJobsStartup(typeof(TestExtensionAStartup))]
|
||||
[assembly: WebJobsStartup(typeof(TestExtensionBStartup))]
|
||||
|
||||
namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
||||
{
|
||||
|
@ -37,8 +36,8 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
private const string Function2Name = "Function2";
|
||||
private const string Function3Name = "Function3";
|
||||
|
||||
internal const string ATriggerType = "testExtensionATrigger";
|
||||
internal const string BTriggerType = "testExtensionBTrigger";
|
||||
internal const string ExtensionTypeA = "testExtensionATrigger";
|
||||
internal const string ExtensionTypeB = "testExtensionBTrigger";
|
||||
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
|
@ -47,9 +46,9 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
{
|
||||
var triggerMetadata = new List<TriggerMetadata>()
|
||||
{
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function1Name}" }, { "type", $"{ATriggerType}" } }),
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function2Name}" }, { "type", $"{ATriggerType}" } }),
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function3Name}" }, { "type", $"{BTriggerType}" } }, new Dictionary<string, object> { { "foo", "bar" } })
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function1Name}" }, { "type", $"{ExtensionTypeA}" } }),
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function2Name}" }, { "type", $"{ExtensionTypeA}" } }),
|
||||
new TriggerMetadata(new JObject { { "functionName", $"{Function3Name}" }, { "type", $"{ExtensionTypeB}" } }, new Dictionary<string, object> { { "foo", "bar" } })
|
||||
};
|
||||
|
||||
string hostJson =
|
||||
|
@ -92,16 +91,19 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
services.AddAzureStorageScaleServices();
|
||||
|
||||
services.AddSingleton<IConcurrencyStatusRepository, TestConcurrencyStatusRepository>();
|
||||
services.AddSingleton<ITriggerMetadataProvider>(new TestTriggerMetadataProvider(triggerMetadata));
|
||||
})
|
||||
.ConfigureWebJobsScale((context, builder) =>
|
||||
{
|
||||
builder.UseHostId(hostId);
|
||||
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
var scaleHostBuilderContext = new ScaleHostBuilderContext(triggerMetadata);
|
||||
new DefaultStartupTypeLocator(assembly);
|
||||
builder.UseExternalStartup(new DefaultStartupTypeLocator(assembly), scaleHostBuilderContext, NullLoggerFactory.Instance);
|
||||
var webJobsBuilderContext = new WebJobsBuilderContext
|
||||
{
|
||||
Configuration = context.Configuration,
|
||||
EnvironmentName = context.HostingEnvironment.EnvironmentName
|
||||
};
|
||||
webJobsBuilderContext.Properties["IsAzureWebJobsScaleHost"] = true;
|
||||
builder.UseExternalStartup(new DefaultStartupTypeLocator(Assembly.GetExecutingAssembly()), webJobsBuilderContext, NullLoggerFactory.Instance);
|
||||
},
|
||||
scaleOptions =>
|
||||
{
|
||||
|
@ -114,6 +116,12 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
IHost scaleHost = hostBuilder.Build();
|
||||
await scaleHost.StartAsync();
|
||||
|
||||
VerifyHostConfiguration(scaleHost);
|
||||
await VerifyScaleLogsAsync(scaleHost, tbsEnabled, loggerProvider);
|
||||
}
|
||||
|
||||
private void VerifyHostConfiguration(IHost scaleHost)
|
||||
{
|
||||
IHostedService scaleMonitorService = scaleHost.Services.GetService<IHostedService>();
|
||||
Assert.NotNull(scaleMonitorService);
|
||||
|
||||
|
@ -125,10 +133,13 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
|
||||
// Validate IConfiguration
|
||||
var config = scaleHost.Services.GetService<IConfiguration>();
|
||||
Assert.False(config.GetValue<string>("sovemalue") == "1");
|
||||
Assert.False(config.GetValue<string>("somevalue") == "1");
|
||||
Assert.True(config.GetValue<string>("Microsoft.Azure.WebJobs.Host.EndToEndTests") == "1");
|
||||
Assert.True(config.GetValue<string>("microsoft.azure.webJobs.host.endtoendtests") == "1");
|
||||
}
|
||||
|
||||
private async Task VerifyScaleLogsAsync(IHost scaleHost, bool tbsEnabled, TestLoggerProvider loggerProvider)
|
||||
{
|
||||
await TestHelpers.Await(async () =>
|
||||
{
|
||||
IScaleStatusProvider scaleManager = scaleHost.Services.GetService<IScaleStatusProvider>();
|
||||
|
@ -174,7 +185,7 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
}
|
||||
|
||||
return scaledOut;
|
||||
}, pollingInterval: 1000);
|
||||
}, timeout: 5000, pollingInterval: 1000);
|
||||
}
|
||||
|
||||
private class TestConcurrencyStatusRepository : IConcurrencyStatusRepository
|
||||
|
@ -200,43 +211,9 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class TestExtensionScalerProvider : IScaleMonitorProvider, ITargetScalerProvider
|
||||
{
|
||||
private IOptions<ScaleOptions> _scaleOptions;
|
||||
private IScaleMonitor _scaleMonitor;
|
||||
private ITargetScaler _targetScaler;
|
||||
private TriggerMetadata _triggerMetadata;
|
||||
|
||||
public TestExtensionScalerProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, TriggerMetadata triggerMetadata)
|
||||
{
|
||||
Assert.Equal(scaleOptions.Value.ScaleMetricsMaxAge, TimeSpan.FromMinutes(4));
|
||||
|
||||
_scaleOptions = scaleOptions;
|
||||
_triggerMetadata = triggerMetadata;
|
||||
}
|
||||
|
||||
public IScaleMonitor GetMonitor()
|
||||
{
|
||||
if (_scaleMonitor == null)
|
||||
{
|
||||
_scaleMonitor = new TestScaleMonitor(_triggerMetadata.FunctionName, _triggerMetadata.FunctionName);
|
||||
}
|
||||
return _scaleMonitor;
|
||||
}
|
||||
|
||||
public ITargetScaler GetTargetScaler()
|
||||
{
|
||||
if (_targetScaler == null)
|
||||
{
|
||||
_targetScaler = new TestTargetScaler(_triggerMetadata.FunctionName);
|
||||
}
|
||||
return _targetScaler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TestExtensionA : IWebJobsStartup2
|
||||
public class TestExtensionAStartup : IWebJobsStartup2
|
||||
{
|
||||
public void Configure(IWebJobsBuilder builder)
|
||||
{
|
||||
|
@ -244,46 +221,19 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
|
||||
public void Configure(WebJobsBuilderContext context, IWebJobsBuilder builder)
|
||||
{
|
||||
var scaleHostBuilderContext = context as ScaleHostBuilderContext;
|
||||
if (scaleHostBuilderContext != null)
|
||||
if (context.Properties.ContainsKey("IsAzureWebJobsScaleHost"))
|
||||
{
|
||||
foreach (var triggerMetadata in scaleHostBuilderContext.GetTriggersMetadata(ATriggerType))
|
||||
{
|
||||
builder.Services.AddSingleton<IScaleMonitorProvider>(serviceProvider =>
|
||||
{
|
||||
IConfiguration config = serviceProvider.GetService<IConfiguration>();
|
||||
IOptions<ScaleOptions> scaleOptions = serviceProvider.GetService<IOptions<ScaleOptions>>();
|
||||
return new TestExtensionAScalerProvider(config, scaleOptions, triggerMetadata);
|
||||
});
|
||||
builder.Services.AddSingleton<ITargetScalerProvider>(serviceProvider =>
|
||||
{
|
||||
IConfiguration config = serviceProvider.GetService<IConfiguration>();
|
||||
IOptions<ScaleOptions> scaleOptions = serviceProvider.GetService<IOptions<ScaleOptions>>();
|
||||
return new TestExtensionAScalerProvider(config, scaleOptions, triggerMetadata);
|
||||
});
|
||||
}
|
||||
builder.Services.AddSingleton<ITargetScalerCollectionProvider, TestExtensionATargetScalerCollectionProvider>();
|
||||
builder.Services.AddSingleton<IScaleMonitorCollectionProvider, TestExtensionAScaleMonitorCollectionProvider>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Configure(builder);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestExtensionAScalerProvider : TestExtensionScalerProvider
|
||||
{
|
||||
public TestExtensionAScalerProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, TriggerMetadata triggerMetadata)
|
||||
: base(config, scaleOptions, triggerMetadata)
|
||||
{
|
||||
// verify we can access configuration settings
|
||||
var appSetting = config.GetValue<string>("app_setting1");
|
||||
Assert.NotNull(appSetting);
|
||||
var hostJsonSetting = config.GetValue<int>("extensions:testExtensionA:foo");
|
||||
Assert.NotNull(hostJsonSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TestExtensionB : IWebJobsStartup2
|
||||
public class TestExtensionBStartup : IWebJobsStartup2
|
||||
{
|
||||
public void Configure(IWebJobsBuilder builder)
|
||||
{
|
||||
|
@ -291,39 +241,155 @@ namespace Microsoft.Azure.WebJobs.Host.EndToEndTests.Scale
|
|||
|
||||
public void Configure(WebJobsBuilderContext context, IWebJobsBuilder builder)
|
||||
{
|
||||
var scaleHostBuilderContext = context as ScaleHostBuilderContext;
|
||||
if (scaleHostBuilderContext != null)
|
||||
if (context.Properties.ContainsKey("IsAzureWebJobsScaleHost"))
|
||||
{
|
||||
foreach (var triggerMetadata in scaleHostBuilderContext.GetTriggersMetadata(BTriggerType))
|
||||
{
|
||||
builder.Services.AddSingleton<IScaleMonitorProvider>(serviceProvider =>
|
||||
{
|
||||
IConfiguration config = serviceProvider.GetService<IConfiguration>();
|
||||
IOptions<ScaleOptions> scaleOptions = serviceProvider.GetService<IOptions<ScaleOptions>>();
|
||||
return new TestExtensionBScalerProvider(config, scaleOptions, triggerMetadata);
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<ITargetScalerProvider>(serviceProvider =>
|
||||
{
|
||||
IConfiguration config = serviceProvider.GetService<IConfiguration>();
|
||||
IOptions<ScaleOptions> scaleOptions = serviceProvider.GetService<IOptions<ScaleOptions>>();
|
||||
return new TestExtensionBScalerProvider(config, scaleOptions, triggerMetadata);
|
||||
});
|
||||
}
|
||||
builder.Services.AddSingleton<ITargetScalerCollectionProvider, TestExtensionBTargetScalerCollectionProvider>();
|
||||
builder.Services.AddSingleton<IScaleMonitorCollectionProvider, TestExtensionBScaleMonitorCollectionProvider>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Configure(builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TestExtensionBScalerProvider : TestExtensionScalerProvider
|
||||
internal class TestTriggerMetadataProvider : ITriggerMetadataProvider
|
||||
{
|
||||
private readonly IReadOnlyCollection<TriggerMetadata> _triggerMetadata;
|
||||
|
||||
public TestTriggerMetadataProvider(List<TriggerMetadata> triggerMetadata)
|
||||
{
|
||||
public TestExtensionBScalerProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, TriggerMetadata triggerMetadata)
|
||||
: base(config, scaleOptions, triggerMetadata)
|
||||
{
|
||||
}
|
||||
_triggerMetadata = triggerMetadata.AsReadOnly();
|
||||
}
|
||||
|
||||
public IEnumerable<TriggerMetadata> GetTriggerMetadata()
|
||||
{
|
||||
return _triggerMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class TestTargetScalerCollectionProvider : ITargetScalerCollectionProvider
|
||||
{
|
||||
private readonly TriggerMetadata[] _triggerMetadata;
|
||||
private readonly object _lock = new object();
|
||||
private ITargetScaler[] _targetScalers;
|
||||
|
||||
public TestTargetScalerCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
{
|
||||
Assert.Equal(scaleOptions.Value.ScaleMetricsMaxAge, TimeSpan.FromMinutes(4));
|
||||
|
||||
_triggerMetadata = triggerMetadataProvider.GetTriggerMetadata().Where(p => string.Compare(p.Type, ExtensionType, StringComparison.OrdinalIgnoreCase) == 0).ToArray();
|
||||
}
|
||||
|
||||
public abstract string ExtensionType { get; }
|
||||
|
||||
public IEnumerable<ITargetScaler> GetTargetScalers()
|
||||
{
|
||||
if (_targetScalers == null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_targetScalers == null)
|
||||
{
|
||||
List<ITargetScaler> targetScalers = new List<ITargetScaler>();
|
||||
foreach (var triggerMetadata in _triggerMetadata)
|
||||
{
|
||||
var targetScaler = new TestTargetScaler(triggerMetadata.FunctionName);
|
||||
targetScalers.Add(targetScaler);
|
||||
}
|
||||
_targetScalers = targetScalers.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _targetScalers;
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class TestScaleMonitorCollectionProvider : IScaleMonitorCollectionProvider
|
||||
{
|
||||
private readonly TriggerMetadata[] _triggerMetadata;
|
||||
private readonly object _lock = new object();
|
||||
private IScaleMonitor[] _scaleMonitors;
|
||||
|
||||
public TestScaleMonitorCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
{
|
||||
Assert.Equal(scaleOptions.Value.ScaleMetricsMaxAge, TimeSpan.FromMinutes(4));
|
||||
|
||||
_triggerMetadata = triggerMetadataProvider.GetTriggerMetadata().Where(p => string.Compare(p.Type, ExtensionType, StringComparison.OrdinalIgnoreCase) == 0).ToArray();
|
||||
}
|
||||
|
||||
public abstract string ExtensionType { get; }
|
||||
|
||||
public IEnumerable<IScaleMonitor> GetScaleMonitors()
|
||||
{
|
||||
if (_scaleMonitors == null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_scaleMonitors == null)
|
||||
{
|
||||
List<IScaleMonitor> scaleMonitors = new List<IScaleMonitor>();
|
||||
foreach (var triggerMetadata in _triggerMetadata)
|
||||
{
|
||||
var monitor = new TestScaleMonitor(triggerMetadata.FunctionName, triggerMetadata.FunctionName);
|
||||
scaleMonitors.Add(monitor);
|
||||
}
|
||||
_scaleMonitors = scaleMonitors.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _scaleMonitors;
|
||||
}
|
||||
}
|
||||
|
||||
internal class TestExtensionATargetScalerCollectionProvider : TestTargetScalerCollectionProvider
|
||||
{
|
||||
public TestExtensionATargetScalerCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
: base(config, scaleOptions, triggerMetadataProvider)
|
||||
{
|
||||
// verify we can access configuration settings
|
||||
var appSetting = config.GetValue<string>("app_setting1");
|
||||
Assert.NotNull(appSetting);
|
||||
var hostJsonSetting = config.GetValue<int>("extensions:testExtensionA:foo");
|
||||
Assert.NotNull(hostJsonSetting);
|
||||
}
|
||||
|
||||
public override string ExtensionType => ExtensionTypeA;
|
||||
}
|
||||
|
||||
internal class TestExtensionAScaleMonitorCollectionProvider : TestScaleMonitorCollectionProvider
|
||||
{
|
||||
public TestExtensionAScaleMonitorCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
: base(config, scaleOptions, triggerMetadataProvider)
|
||||
{
|
||||
// verify we can access configuration settings
|
||||
var appSetting = config.GetValue<string>("app_setting1");
|
||||
Assert.NotNull(appSetting);
|
||||
var hostJsonSetting = config.GetValue<int>("extensions:testExtensionA:foo");
|
||||
Assert.NotNull(hostJsonSetting);
|
||||
}
|
||||
|
||||
public override string ExtensionType => ExtensionTypeA;
|
||||
}
|
||||
|
||||
internal class TestExtensionBTargetScalerCollectionProvider : TestTargetScalerCollectionProvider
|
||||
{
|
||||
public TestExtensionBTargetScalerCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
: base(config, scaleOptions, triggerMetadataProvider)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ExtensionType => ExtensionTypeB;
|
||||
}
|
||||
|
||||
internal class TestExtensionBScaleMonitorCollectionProvider : TestScaleMonitorCollectionProvider
|
||||
{
|
||||
public TestExtensionBScaleMonitorCollectionProvider(IConfiguration config, IOptions<ScaleOptions> scaleOptions, ITriggerMetadataProvider triggerMetadataProvider)
|
||||
: base(config, scaleOptions, triggerMetadataProvider)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ExtensionType => ExtensionTypeB;
|
||||
}
|
||||
|
||||
internal class TestScaleMonitor : IScaleMonitor
|
||||
|
|
|
@ -313,7 +313,9 @@ namespace Microsoft.Azure.WebJobs.Host.UnitTests
|
|||
"AggregateScaleStatus",
|
||||
"IListenerDecorator",
|
||||
"ListenerDecoratorContext",
|
||||
"ScaleHostBuilderContext"
|
||||
"ITriggerMetadataProvider",
|
||||
"ITargetScalerCollectionProvider",
|
||||
"IScaleMonitorCollectionProvider"
|
||||
};
|
||||
|
||||
TestHelpers.AssertPublicTypes(expected, assembly);
|
||||
|
|
Загрузка…
Ссылка в новой задаче