Skip to content
Open
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
3 changes: 2 additions & 1 deletion Splitio.Redis/Services/Client/Classes/RedisClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ public class RedisClient : SplitClient
private ConnectionPoolManager _connectionPoolManager;
private IFeatureFlagCacheConsumer _featureFlagCacheConsumer;

public RedisClient(ConfigurationOptions config, string apiKey) : base(apiKey, config)
public RedisClient(ConfigurationOptions config, string apiKey) : base(apiKey)
{
_config = new RedisConfig();

ReadConfig(config);

BuildFallbackCalculator(config.FallbackTreatments);
BuildRedisCache();
BuildTreatmentLog(config.ImpressionListener);

Expand Down
4 changes: 2 additions & 2 deletions src/Splitio/Services/Client/Classes/JSONFileClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Splitio.Domain;
using Splitio.Services.Cache.Classes;
using Splitio.Services.Cache.Interfaces;
using Splitio.Services.Common;
using Splitio.Services.EngineEvaluator;
using Splitio.Services.Events.Interfaces;
using Splitio.Services.Impressions.Classes;
Expand Down Expand Up @@ -33,7 +32,7 @@ public JSONFileClient(string splitsFilePath,
ITrafficTypeValidator trafficTypeValidator = null,
IImpressionsManager impressionsManager = null,
IRuleBasedSegmentCache ruleBasedSegmentCache = null
) : base("localhost", config)
) : base("localhost")
{
_segmentCache = segmentCacheInstance ?? new InMemorySegmentCache(new ConcurrentDictionary<string, Segment>(), _eventsManager);
var rbsCache = ruleBasedSegmentCache ?? new InMemoryRuleBasedSegmentCache(new ConcurrentDictionary<string, RuleBasedSegment>(), _eventsManager);
Expand All @@ -53,6 +52,7 @@ public JSONFileClient(string splitsFilePath,
parsedSplits.TryAdd(split.name, _splitParser.Parse(split, rbsCache));
}

BuildFallbackCalculator(config.FallbackTreatments);
BuildFlagSetsFilter(new HashSet<string>());
_featureFlagCache = featureFlagCacheInstance ?? new InMemorySplitCache(new ConcurrentDictionary<string, ParsedSplit>(parsedSplits), _flagSetsFilter, _eventsManager);
_impressionsLog = impressionsLog;
Expand Down
3 changes: 2 additions & 1 deletion src/Splitio/Services/Client/Classes/LocalhostClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class LocalhostClient : SplitClient

private readonly object _lock = new object();

public LocalhostClient(ConfigurationOptions configurationOptions) : base("localhost", configurationOptions)
public LocalhostClient(ConfigurationOptions configurationOptions) : base("localhost")
{
var configs = (LocalhostClientConfigurations)_configService.ReadConfig(configurationOptions, ConfigTypes.Localhost, _statusManager);

Expand All @@ -44,6 +44,7 @@ public LocalhostClient(ConfigurationOptions configurationOptions) : base("localh
_localhostFileService = new LocalhostFileService();
}

BuildFallbackCalculator(configurationOptions.FallbackTreatments);
BuildFlagSetsFilter(new HashSet<string>());

var splits = _localhostFileService.ParseSplitFile(_fullPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ public class SelfRefreshingClient : SplitClient
private IRuleBasedSegmentCache _ruleBasedSegmentCache;
private IUpdater<RuleBasedSegmentDto> _ruleBasedSegmentUpdater;

public SelfRefreshingClient(string apiKey, ConfigurationOptions config) : base(apiKey, config)
public SelfRefreshingClient(string apiKey, ConfigurationOptions config) : base(apiKey)
{
_config = (SelfRefreshingConfig)_configService.ReadConfig(config, ConfigTypes.InMemory);

BuildFallbackCalculator(config.FallbackTreatments);
BuildFlagSetsFilter(_config.FlagSetsFilter);
BuildSplitCache();
BuildSegmentCache();
Expand Down
16 changes: 11 additions & 5 deletions src/Splitio/Services/Client/Classes/SplitClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public abstract class SplitClient : ISplitClient
protected readonly IConfigService _configService;
protected readonly IFlagSetsValidator _flagSetsValidator;
protected readonly string ApiKey;
protected readonly FallbackTreatmentCalculator _fallbackTreatmentCalculator;

protected ISplitManager _manager;
protected IEventsLog _eventsLog;
Expand All @@ -63,16 +62,18 @@ public abstract class SplitClient : ISplitClient
protected IImpressionsObserver _impressionsObserver;
protected IClientExtensionService _clientExtensionService;
protected IFlagSetsFilter _flagSetsFilter;
public IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;
protected FallbackTreatmentCalculator _fallbackTreatmentCalculator;
protected IEventsManager<SdkEvent, SdkInternalEvent, EventMetadata> _eventsManager;
private EventHandler<EventMetadata> SdkReadyEvent;

public event EventHandler<EventMetadata> SdkReady
{
add
{
SdkReadyEvent = (EventHandler<EventMetadata>)Delegate.Combine(SdkReadyEvent, value);
if (_eventsManager.EventAlreadyTriggered(SdkEvent.SdkReady))
{
SdkReadyEvent.Invoke(this, null);
SdkReadyEvent.Invoke(this, new EventMetadata(new Dictionary<string, object>()));
}
}

Expand All @@ -84,10 +85,9 @@ public event EventHandler<EventMetadata> SdkReady
public event EventHandler<EventMetadata> SdkUpdate;
public event EventHandler<EventMetadata> SdkTimedOut;

protected SplitClient(string apikey, ConfigurationOptions options)
protected SplitClient(string apikey)
{
ApiKey = apikey;
_fallbackTreatmentCalculator = new FallbackTreatmentCalculator(options.FallbackTreatments);
_eventsManager = new EventsManager<SdkEvent, SdkInternalEvent, EventMetadata>(new EventsManagerConfig(), new EventDelivery<SdkEvent, EventMetadata>());
RegisterEvents();

Expand Down Expand Up @@ -445,6 +445,12 @@ protected void BuildFlagSetsFilter(HashSet<string> sets)
{
_flagSetsFilter = new FlagSetsFilter(sets);
}

protected void BuildFallbackCalculator(FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration)
{
FallbackTreatmentsValidator fallbackTreatmentsValidator = new FallbackTreatmentsValidator();
_fallbackTreatmentCalculator = new FallbackTreatmentCalculator(fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration));
}
#endregion

#region Private Async Methods
Expand Down
1 change: 0 additions & 1 deletion src/Splitio/Services/Common/EventDelivery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public virtual void Deliver(E sdkEvent, M eventMetadata, Action<M> handler)
{
if (handler != null)
{
_logger.Debug($"EventDelivery: Triggering handle for Sdk Event {sdkEvent}");
try
{
handler.Invoke(eventMetadata);
Expand Down
2 changes: 0 additions & 2 deletions src/Splitio/Services/Common/EventsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public void NotifyInternalEvent(I sdkInternalEvent, M eventMetadata)
{
lock (_lock)
{
_logger.Debug($"EventsManager: Handling internal event {sdkInternalEvent}");
foreach (E sortedEvent in _managerConfig.EvaluationOrder.Where(x => GetSdkEventIfApplicable(sdkInternalEvent).Contains(x)))
{
_logger.Debug($"EventsManager: Firing Sdk event {sortedEvent}");
Expand Down Expand Up @@ -93,7 +92,6 @@ public void UpdateSdkInternalEventStatus(I sdkInternalEvent, bool status)
{
_internalEventsStatus.AddOrUpdate(sdkInternalEvent, status,
(_, oldValue) => status);
_logger.Debug($"EventsManager: Internal Event {sdkInternalEvent} status is updated to {status}");
}
#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class FallbackTreatmentsValidator : IFallbackTreatmentsValidator

private readonly ISplitLogger _log = WrapperAdapter.Instance().GetLogger(typeof(FallbackTreatmentsValidator));

public FallbackTreatmentsConfiguration validate(FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration, Enums.API method)
public FallbackTreatmentsConfiguration validate(FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration)
{
FallbackTreatmentsConfiguration processedFallback = new FallbackTreatmentsConfiguration();
if (fallbackTreatmentsConfiguration == null)
Expand All @@ -27,29 +27,33 @@ public FallbackTreatmentsConfiguration validate(FallbackTreatmentsConfiguration
if (fallbackTreatmentsConfiguration.GlobalFallbackTreatment != null)
{
processedGlobalFallbackTreatment = new FallbackTreatment(
IsValidTreatment(fallbackTreatmentsConfiguration.GlobalFallbackTreatment.Treatment, method),
IsValidTreatment(fallbackTreatmentsConfiguration.GlobalFallbackTreatment.Treatment),
fallbackTreatmentsConfiguration.GlobalFallbackTreatment.Config);
if (processedGlobalFallbackTreatment.Treatment == null)
{
processedGlobalFallbackTreatment = null;
}
}

if (fallbackTreatmentsConfiguration.ByFlagFallbackTreatment != null)
{
processedByFlagFallbackTreatment = IsValidByFlagTreatment(fallbackTreatmentsConfiguration.ByFlagFallbackTreatment, method);
processedByFlagFallbackTreatment = IsValidByFlagTreatment(fallbackTreatmentsConfiguration.ByFlagFallbackTreatment);
}
return new FallbackTreatmentsConfiguration(processedGlobalFallbackTreatment, processedByFlagFallbackTreatment);
}

public string IsValidTreatment(string name, Enums.API method)
public string IsValidTreatment(string name)
{
if (string.IsNullOrEmpty(name))
{
_log.Error($"{method}: you passed a null or empty treatment, fallback treatment must be a non-empty string");
_log.Error($"FallbackTreatments: you passed a null or empty treatment, fallback treatment must be a non-empty string");
return null;
}

string trimmed = name.Trim();
if (!trimmed.Equals(name))
{
_log.Warn($"{method}: fallback treatment %s has extra whitespace, trimming");
_log.Warn($"FallbackTreatments: fallback treatment %s has extra whitespace, trimming");
name = trimmed;
}

Expand All @@ -60,26 +64,26 @@ public string IsValidTreatment(string name, Enums.API method)

if (!Regex.IsMatch(name, TreatmentMatcher, RegexOptions.None, TimeSpan.FromMilliseconds(100)))
{
_log.Error($"{method}: you passed {name}, treatment must adhere to the regular expression {TreatmentMatcher}");
_log.Error($"FallbackTreatments: you passed {name}, treatment must adhere to the regular expression {TreatmentMatcher}");
return null;
}

return name;
}

public Dictionary<string, FallbackTreatment> IsValidByFlagTreatment(Dictionary<string, FallbackTreatment> byFlagTreatment, Enums.API method)
public Dictionary<string, FallbackTreatment> IsValidByFlagTreatment(Dictionary<string, FallbackTreatment> byFlagTreatment)
{
Dictionary<string, FallbackTreatment> result = new Dictionary<string, FallbackTreatment>();
foreach (var entry in byFlagTreatment)
{
string featureName = new SplitNameValidator(_log).SplitNameIsValid(entry.Key, method).Value;
string featureName = new SplitNameValidator(_log).SplitNameIsValid(entry.Key, Enums.API.Split).Value;
if (string.IsNullOrEmpty(featureName))
{
continue;
}

FallbackTreatment fallbackTreatment = entry.Value;
string treatment = IsValidTreatment(fallbackTreatment.Treatment, method);
string treatment = IsValidTreatment(fallbackTreatment.Treatment);
if (treatment != null)
{
result.Add(featureName, new FallbackTreatment(treatment, fallbackTreatment.Config));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Splitio.Services.InputValidation.Interfaces
{
public interface IFallbackTreatmentsValidator
{
FallbackTreatmentsConfiguration validate(FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration, Enums.API method);
FallbackTreatmentsConfiguration validate(FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ public SplitClientForTesting(IFeatureFlagCacheConsumer featureFlagCacheConsumer,
ISyncManager syncManager,
ITelemetryEvaluationProducer telemetryEvaluationProducer,
ConfigurationOptions config)
: base("SplitClientForTesting", config)
: base("SplitClientForTesting")
{
BuildFallbackCalculator(config.FallbackTreatments);
_eventsLog = eventsLog;
_impressionsLog = impressionsLog;
_blockUntilReadyService = blockUntilReadyService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public async Task PeriodicTask_ShouldSendBulk()
// Assert.
Assert.IsTrue(_uniqueKeysTracker.Track("key-test", "feature-name-test"));

System.Threading.SpinWait.SpinUntil(() => _cache.Count == 0, TimeSpan.FromMilliseconds(2000));
System.Threading.SpinWait.SpinUntil(() => _cache.IsEmpty, TimeSpan.FromMilliseconds(2000));
_senderAdapter.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Once);

Assert.IsTrue(_uniqueKeysTracker.Track("key-test", "feature-name-test"));
Expand Down Expand Up @@ -104,7 +104,7 @@ public void Track_WithFullSize_ShouldSendTwoBulk()
Thread.Sleep(1000);
Assert.IsTrue(_uniqueKeysTracker.Track("key-test-2", "feature-name-test-6"));

System.Threading.SpinWait.SpinUntil(() => _cache.Count==0, TimeSpan.FromMilliseconds(3000));
System.Threading.SpinWait.SpinUntil(() => _cache.IsEmpty, TimeSpan.FromMilliseconds(3000));
_senderAdapter.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Exactly(2));

_cache.Clear();
Expand Down Expand Up @@ -144,7 +144,7 @@ public void Track_WithFullSize_ShouldSplitBulks()
Assert.IsTrue(_uniqueKeysTracker2.Track("key-test-5", "feature-name-test-2"));
Assert.IsTrue(_uniqueKeysTracker2.Track("key-test-6", "feature-name-test-2"));

System.Threading.SpinWait.SpinUntil(() => _cache2.Count == 0, TimeSpan.FromMilliseconds(3000));
System.Threading.SpinWait.SpinUntil(() => _cache2.IsEmpty, TimeSpan.FromMilliseconds(3000));
_senderAdapter2.Verify(mock => mock.RecordUniqueKeysAsync(It.IsAny<List<Mtks>>()), Times.Exactly(4));

_cache2.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,46 @@ public void Works()
FallbackTreatmentsValidator fallbackTreatmentsValidator = new FallbackTreatmentsValidator();

FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(new FallbackTreatment("12#2"));
Assert.AreEqual(null, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment).GlobalFallbackTreatment.Treatment);
Assert.AreEqual(null, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration).GlobalFallbackTreatment);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration("12#2");
Assert.AreEqual(null, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment).GlobalFallbackTreatment.Treatment);
Assert.AreEqual(null, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration).GlobalFallbackTreatment);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(
new Dictionary<string, FallbackTreatment>() { { "flag", new FallbackTreatment("12#2") } });
Assert.AreEqual(0, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment).ByFlagFallbackTreatment.Count);
Assert.AreEqual(0, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration).ByFlagFallbackTreatment.Count);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(
new Dictionary<string, string>() { { "flag", "12#2" } });
Assert.AreEqual(0, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment).ByFlagFallbackTreatment.Count);
Assert.AreEqual(0, fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration).ByFlagFallbackTreatment.Count);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(
new FallbackTreatment("on"),
new Dictionary<string, FallbackTreatment>() { { "flag", new FallbackTreatment("off") } });
var processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment);
var processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration);
Assert.AreEqual("on", processed.GlobalFallbackTreatment.Treatment);
processed.ByFlagFallbackTreatment.TryGetValue("flag", out FallbackTreatment fallbackTreatment);
Assert.AreEqual("off", fallbackTreatment.Treatment);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration("on",
new Dictionary<string, FallbackTreatment>() { { "flag", new FallbackTreatment("off") } });
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment);
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration);
Assert.AreEqual("on", processed.GlobalFallbackTreatment.Treatment);
processed.ByFlagFallbackTreatment.TryGetValue("flag", out FallbackTreatment fallbackTreatment2);
Assert.AreEqual("off", fallbackTreatment2.Treatment);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(
new FallbackTreatment("on"),
new Dictionary<string, string>() { { "flag", "off" } });
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment);
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration);
Assert.AreEqual("on", processed.GlobalFallbackTreatment.Treatment);
processed.ByFlagFallbackTreatment.TryGetValue("flag", out fallbackTreatment);
Assert.AreEqual("off", fallbackTreatment.Treatment);

fallbackTreatmentsConfiguration = new FallbackTreatmentsConfiguration(
new FallbackTreatment("on"),
new Dictionary<string, string>() { { "flag", "off" } });
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration, Splitio.Enums.API.GetTreatment);
processed = fallbackTreatmentsValidator.validate(fallbackTreatmentsConfiguration);
Assert.AreEqual("on", processed.GlobalFallbackTreatment.Treatment);
processed.ByFlagFallbackTreatment.TryGetValue("flag", out fallbackTreatment);
Assert.AreEqual("off", fallbackTreatment.Treatment);
Expand Down
5 changes: 2 additions & 3 deletions tests/Splitio.TestSupport/SplitClientForTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Splitio.Domain;
using Splitio.Services.Common;
using Splitio.Services.Impressions.Classes;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand All @@ -10,8 +8,9 @@ public class SplitClientForTest : SplitClient
{
private readonly Dictionary<string, string> _tests;

public SplitClientForTest(ConfigurationOptions config) : base("SplitClientForTest", config)
public SplitClientForTest(ConfigurationOptions config) : base("SplitClientForTest")
{
BuildFallbackCalculator(config.FallbackTreatments);
_tests = new Dictionary<string, string>();
}

Expand Down
Loading