1010using System . Net . Http ;
1111using System . Resources ;
1212using System . Threading . Tasks ;
13+ using Microsoft . Azure . WebJobs . Script . Config ;
1314using Microsoft . Azure . WebJobs . Script . Configuration ;
1415using Microsoft . Azure . WebJobs . Script . Diagnostics . Extensions ;
1516using Microsoft . Azure . WebJobs . Script . Models ;
1617using Microsoft . Extensions . Logging ;
18+ using Microsoft . WindowsAzure . Storage . Shared . Protocol ;
1719using Newtonsoft . Json ;
1820using NuGet . Versioning ;
1921
@@ -23,16 +25,18 @@ public class ExtensionBundleManager : IExtensionBundleManager
2325 {
2426 private readonly IEnvironment _environment ;
2527 private readonly ExtensionBundleOptions _options ;
28+ private readonly FunctionsHostingConfigOptions _configOption ;
2629 private readonly ILogger _logger ;
2730 private readonly string _cdnUri ;
2831 private string _extensionBundleVersion ;
2932
30- public ExtensionBundleManager ( ExtensionBundleOptions options , IEnvironment environment , ILoggerFactory loggerFactory )
33+ public ExtensionBundleManager ( ExtensionBundleOptions options , IEnvironment environment , ILoggerFactory loggerFactory , FunctionsHostingConfigOptions configOption )
3134 {
3235 _environment = environment ?? throw new ArgumentNullException ( nameof ( environment ) ) ;
3336 _logger = loggerFactory . CreateLogger < ExtensionBundleManager > ( ) ?? throw new ArgumentNullException ( nameof ( loggerFactory ) ) ;
3437 _cdnUri = _environment . GetEnvironmentVariable ( EnvironmentSettingNames . ExtensionBundleSourceUri ) ?? ScriptConstants . ExtensionBundleDefaultSourceUri ;
3538 _options = options ?? throw new ArgumentNullException ( nameof ( options ) ) ;
39+ _configOption = configOption ?? throw new ArgumentNullException ( nameof ( configOption ) ) ;
3640 }
3741
3842 public async Task < ExtensionBundleDetails > GetExtensionBundleDetails ( )
@@ -128,7 +132,7 @@ internal bool TryLocateExtensionBundle(out string bundlePath)
128132 if ( FileUtility . DirectoryExists ( path ) )
129133 {
130134 var bundleDirectories = FileUtility . EnumerateDirectories ( path ) ;
131- string version = FindBestVersionMatch ( _options . Version , bundleDirectories ) ;
135+ string version = FindBestVersionMatch ( _options . Version , bundleDirectories , _options . Id , _configOption ) ;
132136
133137 if ( ! string . IsNullOrEmpty ( version ) )
134138 {
@@ -236,7 +240,8 @@ private async Task<string> GetLatestMatchingBundleVersionAsync(HttpClient httpCl
236240
237241 var content = await response . Content . ReadAsStringAsync ( ) ;
238242 var bundleVersions = JsonConvert . DeserializeObject < IEnumerable < string > > ( content ) ;
239- var matchingBundleVersion = FindBestVersionMatch ( _options . Version , bundleVersions ) ;
243+
244+ var matchingBundleVersion = FindBestVersionMatch ( _options . Version , bundleVersions , _options . Id , _configOption ) ;
240245
241246 if ( string . IsNullOrEmpty ( matchingBundleVersion ) )
242247 {
@@ -246,7 +251,7 @@ private async Task<string> GetLatestMatchingBundleVersionAsync(HttpClient httpCl
246251 return matchingBundleVersion ;
247252 }
248253
249- private static string FindBestVersionMatch ( VersionRange versionRange , IEnumerable < string > versions )
254+ internal static string FindBestVersionMatch ( VersionRange versionRange , IEnumerable < string > versions , string bundleId , FunctionsHostingConfigOptions configOption )
250255 {
251256 var bundleVersions = versions . Select ( p =>
252257 {
@@ -259,7 +264,29 @@ private static string FindBestVersionMatch(VersionRange versionRange, IEnumerabl
259264 return version ;
260265 } ) . Where ( v => v != null ) ;
261266
262- return bundleVersions . OrderByDescending ( version => version . Version ) . FirstOrDefault ( ) ? . ToString ( ) ;
267+ var matchingVersion = bundleVersions . OrderByDescending ( version => version . Version ) . FirstOrDefault ( ) ;
268+
269+ if ( bundleId != ScriptConstants . DefaultExtensionBundleId )
270+ {
271+ return matchingVersion ? . ToString ( ) ;
272+ }
273+
274+ var maximumBundleV3Version = NuGetVersion . Parse ( configOption . MaximumSupportedBundleV3Version ) ;
275+ matchingVersion = matchingVersion ? . Major == 3 && matchingVersion > maximumBundleV3Version
276+ ? maximumBundleV3Version
277+ : matchingVersion ;
278+
279+ var maximumBundleV4Version = NuGetVersion . Parse ( configOption . MaximumSupportedBundleV4Version ) ;
280+ matchingVersion = matchingVersion ? . Major == 4 && matchingVersion > maximumBundleV4Version
281+ ? maximumBundleV4Version
282+ : matchingVersion ;
283+
284+ if ( matchingVersion ? . Major > 4 )
285+ {
286+ throw new HostInitializationException ( $ "Referenced bundle { bundleId } of version { matchingVersion } does not meet the requirements for maximum supported version for extension bundle. Update your extension bundle reference in host.json to reference bundle version { maximumBundleV4Version } or lower.") ;
287+ }
288+
289+ return matchingVersion ? . ToString ( ) ;
263290 }
264291
265292 public async Task < string > GetExtensionBundleBinPathAsync ( )
0 commit comments