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
22 changes: 22 additions & 0 deletions pkgs/sdk/server/contract-tests/Representations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,27 @@ public class SdkConfigPersistentCacheParams
public class SdkConfigDataInitializerParams
{
public SdkConfigPollingParams Polling { get; set; }
public SdkConfigFileDataParams File { get; set; }
}

public class SdkConfigDataSynchronizerParams
{
public SdkConfigStreamingParams Streaming { get; set; }
public SdkConfigPollingParams Polling { get; set; }
public SdkConfigFileDataParams File { get; set; }
public SdkConfigTestDataParams TestData { get; set; }
}

public class SdkConfigFileDataParams
{
public string[] FilePaths { get; set; }
public bool? Persist { get; set; }
}

public class SdkConfigTestDataParams
{
public Dictionary<string, LdValue> Flags { get; set; }
public bool? Persist { get; set; }
}

public class SdkConfigPollingParams
Expand Down Expand Up @@ -244,6 +259,7 @@ public class CommandParams
public RegisterFlagChangeListenerParams RegisterFlagChangeListener { get; set; }
public RegisterFlagValueChangeListenerParams RegisterFlagValueChangeListener { get; set; }
public UnregisterListenerParams UnregisterListener { get; set; }
public UpdateTestDataParams UpdateTestData { get; set; }
}

public class ContextComparisonPairParams
Expand Down Expand Up @@ -304,6 +320,12 @@ public class UnregisterListenerParams
public string ListenerId { get; set; }
}

public class UpdateTestDataParams
{
public string FlagKey { get; set; }
public LdValue Value { get; set; }
}

public class ListenerNotification
{
public string ListenerId { get; set; }
Expand Down
73 changes: 71 additions & 2 deletions pkgs/sdk/server/contract-tests/SdkClientEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public class SdkClientEntity
private readonly Logger _log;
private readonly Dictionary<string, EventHandler<FlagChangeEvent>> _flagListeners =
new Dictionary<string, EventHandler<FlagChangeEvent>>();
// The test data source of this client, if the configuration has a testData synchronizer. The
// harness sends at most one.
private TestData _testData;

public SdkClientEntity(
SdkConfigParams sdkParams,
Expand Down Expand Up @@ -170,6 +173,21 @@ public bool DoCommand(CommandParams command, out object response)
break;
}

case "updateTestData":
{
if (_testData == null)
{
throw new InvalidOperationException("the client has no test data source");
}
var p = command.UpdateTestData;
if (p?.FlagKey == null)
{
throw new ArgumentException("updateTestData requires a flag key");
}
_testData.Update(_testData.Flag(p.FlagKey).ValueForAll(p.Value));
break;
}

default:
return false;
}
Expand Down Expand Up @@ -376,7 +394,7 @@ private ContextBuildResponse DoContextConvert(ContextConvertParams p)
}
}

private static Configuration BuildSdkConfig(SdkConfigParams sdkParams, ILogAdapter logAdapter, string tag)
private Configuration BuildSdkConfig(SdkConfigParams sdkParams, ILogAdapter logAdapter, string tag)
{
var builder = Configuration.Builder(sdkParams.Credential);

Expand Down Expand Up @@ -617,6 +635,10 @@ private static Configuration BuildSdkConfig(SdkConfigParams sdkParams, ILogAdapt
}
initializers.Add(pollingBuilder);
}
else if (initializer.File != null)
{
initializers.Add(CreateFileDataSource(initializer.File, false));
}
}
if (initializers.Count > 0)
{
Expand Down Expand Up @@ -721,7 +743,45 @@ private static FileOverrideSourceBuilder BuildOverrideSource(SdkConfigOverridesP
return source;
}

private static IComponentConfigurer<IDataSource> CreateSynchronizer(
private static FileDataSourceBuilder CreateFileDataSource(SdkConfigFileDataParams p, bool autoUpdate)
{
// A file data source with no files would load an empty data set, which hides LaunchDarkly data
// in memory or, when persisted, empties the store.
if (p.FilePaths == null || p.FilePaths.Length == 0 || p.FilePaths.Any(string.IsNullOrEmpty))
{
throw new ArgumentException("a file data source requires at least one file path");
}
var builder = FileData.DataSource().FilePaths(p.FilePaths).AutoUpdate(autoUpdate);
if (p.Persist.HasValue)
{
builder.ShouldPersist(p.Persist.Value);
}
return builder;
}

private TestData TestDataFor(SdkConfigTestDataParams p)
{
// The updateTestData command addresses the client's test data source, so there is only one.
if (_testData != null)
{
throw new ArgumentException("the configuration has more than one testData synchronizer");
}
_testData = TestData.DataSource();
if (p.Persist.HasValue)
{
_testData.ShouldPersist(p.Persist.Value);
}
if (p.Flags != null)
{
foreach (var flag in p.Flags)
{
_testData.Update(_testData.Flag(flag.Key).ValueForAll(flag.Value));
}
}
return _testData;
}

private IComponentConfigurer<IDataSource> CreateSynchronizer(
SdkConfigDataSynchronizerParams synchronizer,
string payloadFilter)
{
Expand Down Expand Up @@ -763,6 +823,15 @@ private static IComponentConfigurer<IDataSource> CreateSynchronizer(
}
return streamingBuilder;
}
else if (synchronizer.File != null)
{
// A file synchronizer reloads the files when they change.
return CreateFileDataSource(synchronizer.File, true);
}
else if (synchronizer.TestData != null)
{
return TestDataFor(synchronizer.TestData);
}
return null;
}

Expand Down
5 changes: 4 additions & 1 deletion pkgs/sdk/server/contract-tests/TestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ public class Webapp
"instance-id",
"retry-conformance-fdv1-streaming",
"retry-conformance-fdv1-polling",
"flag-overrides"
"flag-overrides",
"file-data-source",
"test-data-source",
"data-source-persist-opt-in"
};

public readonly Handler Handler;
Expand Down
Loading