Skip to content

Commit

Permalink
create the configuration cache in the BaseConfigurationManager class (#…
Browse files Browse the repository at this point in the history
…2048)

* create the configuration cache in the BaseConfigurationManager class

* added a test

* moved all fields/properties of the LastKnownGoodConfigurationCacheOptions class to LKGConfigurationCacheOptions so they are more accessible

* added TaskCreationOptions and RemoveExpiredValues to LKGConfigurationCacheOptions

* added the DefaultLastKnownGoodConfigurationSizeLimit property to fix an ApiCompat error

* review feedback
  • Loading branch information
dannybtsai committed Apr 10, 2023
1 parent 614642a commit 2eb488a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public ConfigurationManager(string metadataAddress, IConfigurationRetriever<T> c
/// <exception cref="ArgumentNullException">If 'docRetriever' is null.</exception>
/// <exception cref="ArgumentNullException">If 'lkgCacheOptions' is null.</exception>
public ConfigurationManager(string metadataAddress, IConfigurationRetriever<T> configRetriever, IDocumentRetriever docRetriever, LastKnownGoodConfigurationCacheOptions lkgCacheOptions)
: base(lkgCacheOptions)
{
if (string.IsNullOrWhiteSpace(metadataAddress))
throw LogHelper.LogArgumentNullException(nameof(metadataAddress));
Expand All @@ -94,23 +95,14 @@ public ConfigurationManager(string metadataAddress, IConfigurationRetriever<T> c
if (docRetriever == null)
throw LogHelper.LogArgumentNullException(nameof(docRetriever));

if (lkgCacheOptions == null)
throw LogHelper.LogArgumentNullException(nameof(lkgCacheOptions));

MetadataAddress = metadataAddress;
_docRetriever = docRetriever;
_configRetriever = configRetriever;
_refreshLock = new SemaphoreSlim(1);

_lastKnownGoodConfigurationCache = new EventBasedLRUCache<BaseConfiguration, DateTime>(
lkgCacheOptions.LastKnownGoodConfigurationSizeLimit,
TaskCreationOptions.None,
lkgCacheOptions.BaseConfigurationComparer,
true);
}

/// <summary>
/// Instantiates a new <see cref="ConfigurationManager{T}"/> with cinfiguration validator that manages automatic and controls refreshing on configuration data.
/// Instantiates a new <see cref="ConfigurationManager{T}"/> with configuration validator that manages automatic and controls refreshing on configuration data.
/// </summary>
/// <param name="metadataAddress">The address to obtain configuration.</param>
/// <param name="configRetriever">The <see cref="IConfigurationRetriever{T}"/></param>
Expand All @@ -123,7 +115,7 @@ public ConfigurationManager(string metadataAddress, IConfigurationRetriever<T> c
}

/// <summary>
/// Instantiates a new <see cref="ConfigurationManager{T}"/> with cinfiguration validator that manages automatic and controls refreshing on configuration data.
/// Instantiates a new <see cref="ConfigurationManager{T}"/> with configuration validator that manages automatic and controls refreshing on configuration data.
/// </summary>
/// <param name="metadataAddress">The address to obtain configuration.</param>
/// <param name="configRetriever">The <see cref="IConfigurationRetriever{T}"/></param>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;

using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens.Configuration;

namespace Microsoft.IdentityModel.Protocols.Configuration
{
/// <summary>
/// Specifies the LastKnownGoodConfigurationCacheOptions which can be used to configure the internal LKG configuration cache.
/// See <see cref="EventBasedLRUCache{TKey, TValue}"/> for more details.
///
/// All fields/properties are now defined in the Microsoft.IdentityModel.Tokens.Configuration.LKGConfigurationCacheOptions class so they are more accessible from other assemblies/classes.
/// </summary>
public class LastKnownGoodConfigurationCacheOptions
public class LastKnownGoodConfigurationCacheOptions : LKGConfigurationCacheOptions
{
private IEqualityComparer<BaseConfiguration> _baseConfigurationComparer = new BaseConfigurationComparer();
private int _lastKnownGoodConfigurationSizeLimit = DefaultLastKnownGoodConfigurationSizeLimit;

/// <summary>
/// 10 is the default size limit of the cache (in number of items) for last known good configuration.
/// </summary>
public static readonly int DefaultLastKnownGoodConfigurationSizeLimit = 10;

/// <summary>
/// Gets or sets the BaseConfgiurationComparer that to compare <see cref="BaseConfiguration"/>.
/// </summary>
public IEqualityComparer<BaseConfiguration> BaseConfigurationComparer
{
get { return _baseConfigurationComparer; }
set
{
_baseConfigurationComparer = value ?? throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(value)));
}
}

/// <summary>
/// The size limit of the cache (in number of items) for last known good configuration.
/// </summary>
public int LastKnownGoodConfigurationSizeLimit
{
get { return _lastKnownGoodConfigurationSizeLimit; }
set
{
_lastKnownGoodConfigurationSizeLimit = (value > 0) ? value : throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(value)));
}
}
/// <inheritdoc/>
public static readonly int DefaultLastKnownGoodConfigurationSizeLimit = LKGConfigurationCacheOptions.DefaultLKGConfigurationSizeLimit;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Protocols.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Protocols.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.Protocols
{
Expand All @@ -23,17 +23,12 @@ public class StaticConfigurationManager<T> : BaseConfigurationManager, IConfigur
/// Initializes an new instance of <see cref="StaticConfigurationManager{T}"/> with a Configuration instance.
/// </summary>
/// <param name="configuration">Configuration of type OpenIdConnectConfiguration or OpenIdConnectConfiguration.</param>
public StaticConfigurationManager(T configuration)
public StaticConfigurationManager(T configuration) : base()
{
if (configuration == null)
throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(configuration), LogHelper.FormatInvariant(LogMessages.IDX20000, LogHelper.MarkAsNonPII(nameof(configuration)))));

_configuration = configuration;
_lastKnownGoodConfigurationCache = new EventBasedLRUCache<BaseConfiguration, DateTime>(
LastKnownGoodConfigurationCacheOptions.DefaultLastKnownGoodConfigurationSizeLimit,
TaskCreationOptions.None,
new BaseConfigurationComparer(),
true);
}

/// <summary>
Expand Down
31 changes: 25 additions & 6 deletions src/Microsoft.IdentityModel.Tokens/BaseConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens.Configuration;

namespace Microsoft.IdentityModel.Tokens
{
Expand All @@ -22,12 +23,7 @@ public abstract class BaseConfigurationManager
private BaseConfiguration _lastKnownGoodConfiguration;
private DateTime? _lastKnownGoodConfigFirstUse = null;

internal EventBasedLRUCache<BaseConfiguration, DateTime> _lastKnownGoodConfigurationCache =
new EventBasedLRUCache<BaseConfiguration, DateTime>(
10,
TaskCreationOptions.None,
new BaseConfigurationComparer(),
true);
internal EventBasedLRUCache<BaseConfiguration, DateTime> _lastKnownGoodConfigurationCache;

/// <summary>
/// Gets or sets the <see cref="TimeSpan"/> that controls how often an automatic metadata refresh should occur.
Expand Down Expand Up @@ -59,6 +55,29 @@ public TimeSpan AutomaticRefreshInterval
/// </summary>
public static readonly TimeSpan DefaultRefreshInterval = new TimeSpan(0, 0, 5, 0);

/// <summary>
/// The default constructor.
/// </summary>
public BaseConfigurationManager() : this(new LKGConfigurationCacheOptions())
{
}

/// <summary>
/// Constructor.
/// </summary>
/// <param name="options">The event queue task creation option.</param>
public BaseConfigurationManager(LKGConfigurationCacheOptions options)
{
if (options == null)
throw LogHelper.LogArgumentNullException(nameof(options));

_lastKnownGoodConfigurationCache = new EventBasedLRUCache<BaseConfiguration, DateTime>(
options.LastKnownGoodConfigurationSizeLimit,
options.TaskCreationOptions,
options.BaseConfigurationComparer,
options.RemoveExpiredValues);
}

/// <summary>
/// Obtains an updated version of <see cref="BaseConfiguration"/> if the appropriate refresh interval has passed.
/// This method may return a cached version of the configuration.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Microsoft.IdentityModel.Tokens.Configuration
{
/// <summary>
/// Defines the options which can be used to configure the internal LKG configuration cache.
/// See <see cref="EventBasedLRUCache{TKey, TValue}"/> for more details.
/// </summary>
public class LKGConfigurationCacheOptions
{
private IEqualityComparer<BaseConfiguration> _baseConfigurationComparer = new BaseConfigurationComparer();
private int _lastKnownGoodConfigurationSizeLimit = DefaultLKGConfigurationSizeLimit;

/// <summary>
/// 10 is the default size limit of the cache (in number of items) for last known good configuration.
/// </summary>
public static readonly int DefaultLKGConfigurationSizeLimit = 10;

/// <summary>
/// Gets or sets the BaseConfgiurationComparer that to compare <see cref="BaseConfiguration"/>.
/// </summary>
public IEqualityComparer<BaseConfiguration> BaseConfigurationComparer
{
get { return _baseConfigurationComparer; }
set { _baseConfigurationComparer = value ?? throw new ArgumentNullException(nameof(value)); }
}

/// <summary>
/// The size limit of the cache (in number of items) for last known good configuration.
/// </summary>
public int LastKnownGoodConfigurationSizeLimit
{
get { return _lastKnownGoodConfigurationSizeLimit; }
set { _lastKnownGoodConfigurationSizeLimit = (value > 0) ? value : throw new ArgumentOutOfRangeException(nameof(value)); }
}

/// <summary>
/// The event queue task creation option, default to None instead of LongRunning as LongRunning will always start a task on a new thread instead of a thread from ThreadPool.
/// </summary>
public TaskCreationOptions TaskCreationOptions { get; set; } = TaskCreationOptions.None;

/// <summary>
/// Whether or not to remove expired items.
/// </summary>
public bool RemoveExpiredValues { get; set; } = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Logging;
Expand All @@ -27,17 +24,12 @@ public class MockConfigurationManager<T> : BaseConfigurationManager, IConfigurat
/// Initializes an new instance of <see cref="MockConfigurationManager{T}"/> with a Configuration instance.
/// </summary>
/// <param name="configuration">Configuration of type OpenIdConnectConfiguration or OpenIdConnectConfiguration.</param>
public MockConfigurationManager(T configuration)
public MockConfigurationManager(T configuration) : base()
{
if (configuration == null)
throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(configuration)));

_configuration = configuration;
_lastKnownGoodConfigurationCache = new EventBasedLRUCache<BaseConfiguration, DateTime>(
LastKnownGoodConfigurationCacheOptions.DefaultLastKnownGoodConfigurationSizeLimit,
TaskCreationOptions.None,
new BaseConfigurationComparer(),
true);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public override string ToString()
/// - parameter validation for Encrypt
/// Decrypt
/// - negative tests for tampering of (ciphertest, iv, authenticationtag, authenticateddata)
/// - parameter validataion for Decrypt
/// - parameter validation for Decrypt
/// DecryptMismatch
/// - negative tests for switching (keys, algorithms)
/// EncryptVirtual
Expand Down

0 comments on commit 2eb488a

Please sign in to comment.