2023-03-07 13:46:52 -05:00
|
|
|
|
using Bit.Core.Context;
|
|
|
|
|
|
using Bit.Core.Settings;
|
2023-03-02 14:04:23 -05:00
|
|
|
|
using LaunchDarkly.Sdk.Server;
|
|
|
|
|
|
using LaunchDarkly.Sdk.Server.Integrations;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Bit.Core.Services;
|
|
|
|
|
|
|
|
|
|
|
|
public class LaunchDarklyFeatureService : IFeatureService, IDisposable
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly LdClient _client;
|
|
|
|
|
|
|
|
|
|
|
|
public LaunchDarklyFeatureService(
|
|
|
|
|
|
IGlobalSettings globalSettings)
|
|
|
|
|
|
{
|
|
|
|
|
|
var ldConfig = Configuration.Builder(globalSettings.LaunchDarkly?.SdkKey);
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(globalSettings.LaunchDarkly?.SdkKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
// support a file to load flag values
|
|
|
|
|
|
if (File.Exists(globalSettings.LaunchDarkly?.FlagDataFilePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
ldConfig.DataSource(
|
|
|
|
|
|
FileData.DataSource()
|
|
|
|
|
|
.FilePaths(globalSettings.LaunchDarkly?.FlagDataFilePath)
|
|
|
|
|
|
.AutoUpdate(true)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// do not provide analytics events
|
|
|
|
|
|
ldConfig.Events(Components.NoEvents);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// when a file-based fallback isn't available, work offline
|
|
|
|
|
|
ldConfig.Offline(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (globalSettings.SelfHosted)
|
|
|
|
|
|
{
|
|
|
|
|
|
// when self-hosted, work offline
|
|
|
|
|
|
ldConfig.Offline(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_client = new LdClient(ldConfig.Build());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsOnline()
|
|
|
|
|
|
{
|
|
|
|
|
|
return _client.Initialized && !_client.IsOffline();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-07 13:46:52 -05:00
|
|
|
|
public bool IsEnabled(string key, ICurrentContext currentContext, bool defaultValue = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _client.BoolVariation(key, BuildContext(currentContext), defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int GetIntVariation(string key, ICurrentContext currentContext, int defaultValue = 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _client.IntVariation(key, BuildContext(currentContext), defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string GetStringVariation(string key, ICurrentContext currentContext, string defaultValue = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _client.StringVariation(key, BuildContext(currentContext), defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-02 14:04:23 -05:00
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
_client?.Dispose();
|
|
|
|
|
|
}
|
2023-03-07 13:46:52 -05:00
|
|
|
|
|
|
|
|
|
|
private LaunchDarkly.Sdk.Context BuildContext(ICurrentContext currentContext)
|
|
|
|
|
|
{
|
|
|
|
|
|
var builder = LaunchDarkly.Sdk.Context.MultiBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
if (currentContext.UserId.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
var user = LaunchDarkly.Sdk.Context.Builder(currentContext.UserId.Value.ToString());
|
|
|
|
|
|
user.Kind(LaunchDarkly.Sdk.ContextKind.Default);
|
|
|
|
|
|
builder.Add(user.Build());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (currentContext.OrganizationId.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
var org = LaunchDarkly.Sdk.Context.Builder(currentContext.OrganizationId.Value.ToString());
|
|
|
|
|
|
org.Kind("org");
|
|
|
|
|
|
builder.Add(org.Build());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return builder.Build();
|
|
|
|
|
|
}
|
2023-03-02 14:04:23 -05:00
|
|
|
|
}
|