Skip to content

Commit baa6aba

Browse files
authored
Merge pull request #147 from Flagsmith/chore/8.0.0
fix!: Remove deprecated methods and constructors. Throw error if using local eval without server-side key
2 parents ceeaf48 + 4686aa9 commit baa6aba

File tree

8 files changed

+69
-924
lines changed

8 files changed

+69
-924
lines changed

Flagsmith.Client.Test/Fixtures.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Flagsmith.FlagsmithClientTest
88
{
99
internal class Fixtures
1010
{
11-
public static string ApiKey => "test_key";
11+
public static string ApiKey => "ser.test_key";
1212
public static string ApiUrl => "http://test_url/";
1313
public static AnalyticsProcessorTest GetAnalyticalProcessorTest() => new(new HttpClient(), ApiKey, ApiUrl);
1414
public static JObject JsonObject = JObject.Parse(@"{

Flagsmith.Client.Test/FlagsmithTest.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
@@ -648,6 +648,27 @@ public void TestCannotCreateFlagsmithClientInRemoteEvaluationWithoutAPIKey()
648648
Assert.Equal("ValueError: environmentKey is required", exception.Message);
649649
}
650650

651+
[Fact]
652+
public void TestCannotCreateFlagsmithClientInLocalEvaluationWithoutServerAPIKey()
653+
{
654+
// When
655+
Action createFlagsmith = () => new FlagsmithClient(
656+
new FlagsmithConfiguration
657+
{
658+
EnvironmentKey = "foobar",
659+
EnableLocalEvaluation = true
660+
}
661+
);
662+
663+
// Then
664+
var exception = Assert.Throws<Exception>(() => createFlagsmith());
665+
Assert.Equal
666+
(
667+
"ValueError: In order to use local evaluation, please generate a server key in the environment settings page.",
668+
exception.Message
669+
);
670+
}
671+
651672
[Fact]
652673
/// <summary>
653674
/// Test that analytics data is consistent with concurrent calls to get flags.
@@ -685,7 +706,7 @@ public async Task TestAnalyticsDataConsistencyWithConcurrentCallsToGetFlags()
685706
featuresDictionary.TryAdd($"Feature_{i}", 0);
686707
}
687708

688-
// When
709+
// When
689710
var tasks = new Task[numberOfThreads];
690711

691712
// Create numberOfThreads threads.
@@ -696,13 +717,13 @@ public async Task TestAnalyticsDataConsistencyWithConcurrentCallsToGetFlags()
696717
// Prepare an array of feature names of length callsPerThread.
697718
for (var j = 0; j < callsPerThread; j++)
698719
{
699-
// The feature names are randomly selected from the featuresDictionary and added to the
700-
// list of features, which represents the features that have been evaluated.
720+
// The feature names are randomly selected from the featuresDictionary and added to the
721+
// list of features, which represents the features that have been evaluated.
701722
string featureName = $"Feature_{new Random().Next(1, featuresDictionary.Count + 1)}";
702723
features[j] = featureName;
703724

704725
// The relevant key in the featuresDictionary is incremented to simulate an evaluation
705-
// to track for that feature.
726+
// to track for that feature.
706727
featuresDictionary[featureName]++;
707728
}
708729

Flagsmith.Client.Test/FlagsmithTestDeprecated.cs

Lines changed: 0 additions & 668 deletions
This file was deleted.
Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>8</LangVersion>
6+
<DefaultItemExcludes>$(DefaultItemExcludes);example/**;</DefaultItemExcludes>
7+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
8+
<PackageId>Flagsmith</PackageId>
9+
<Title>Flagsmith</Title>
10+
<Version>8.0.0</Version>
11+
<Authors>flagsmith</Authors>
12+
<Company>Flagsmith</Company>
13+
<PackageDescription>Client SDK for Flagsmith. Ship features with confidence using feature flags and remote config. Host yourself or use our hosted version at https://flagsmith.com/</PackageDescription>
14+
<Copyright>Copyright © 2023 Bullet Train Ltd</Copyright>
15+
<PackageProjectUrl>https://flagsmith.com/</PackageProjectUrl>
16+
<PackageIcon>icon.png</PackageIcon>
17+
<PackageReleaseNotes>Singleton HTTP client</PackageReleaseNotes>
18+
<PackageTags>feature flags remote config toggles</PackageTags>
19+
<RepositoryUrl>https://github.com/Flagsmith/flagsmith-dotnet-client</RepositoryUrl>
20+
<NeutralLanguage>en-GB</NeutralLanguage>
21+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
22+
</PropertyGroup>
223

3-
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
5-
<LangVersion>8</LangVersion>
6-
<DefaultItemExcludes>$(DefaultItemExcludes);example/**;</DefaultItemExcludes>
7-
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
8-
<PackageId>Flagsmith</PackageId>
9-
<Title>Flagsmith</Title>
10-
<Version>7.1.1</Version>
11-
<Authors>flagsmith</Authors>
12-
<Company>Flagsmith</Company>
13-
<PackageDescription>Client SDK for Flagsmith. Ship features with confidence using feature flags and remote config. Host yourself or use our hosted version at https://flagsmith.com/</PackageDescription>
14-
<Copyright>Copyright © 2023 Bullet Train Ltd</Copyright>
15-
<PackageProjectUrl>https://flagsmith.com/</PackageProjectUrl>
16-
<PackageIcon>icon.png</PackageIcon>
17-
<PackageReleaseNotes>Singleton HTTP client</PackageReleaseNotes>
18-
<PackageTags>feature flags remote config toggles</PackageTags>
19-
<RepositoryUrl>https://github.com/Flagsmith/flagsmith-dotnet-client</RepositoryUrl>
20-
<NeutralLanguage>en-GB</NeutralLanguage>
21-
<PackageLicenseFile>LICENSE</PackageLicenseFile>
22-
</PropertyGroup>
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0"/>
26+
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
27+
<PackageReference Include="Polly" Version="7.2.3"/>
28+
<PackageReference Include="Teronis.MSBuild.Packaging.ProjectBuildInPackage" Version="1.0.0">
29+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
30+
<PrivateAssets>all</PrivateAssets>
31+
</PackageReference>
2332

24-
<ItemGroup>
25-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
26-
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
27-
<PackageReference Include="Polly" Version="7.2.3" />
28-
<PackageReference Include="Teronis.MSBuild.Packaging.ProjectBuildInPackage" Version="1.0.0">
29-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
30-
<PrivateAssets>all</PrivateAssets>
31-
</PackageReference>
33+
<!-- currently we duplicate the semver dependency here from Engine project -->
34+
<!-- TODO: build the Engine at build time and reference it using a PackageReference -->
35+
<PackageReference Include="semver" Version="2.3.0"/>
3236

33-
<!-- currently we duplicate the semver dependency here from Engine project -->
34-
<!-- TODO: build the Engine at build time and reference it using a PackageReference -->
35-
<PackageReference Include="semver" Version="2.3.0" />
36-
37-
<ProjectReference Include="..\Flagsmith.Engine\Flagsmith.Engine.csproj" PrivateAssets="all" />
38-
<None Include="LICENSE" Pack="true" PackagePath="" />
39-
<None Include="icon.png" Pack="true" PackagePath="\" />
40-
</ItemGroup>
37+
<ProjectReference Include="..\Flagsmith.Engine\Flagsmith.Engine.csproj" PrivateAssets="all"/>
38+
<None Include="LICENSE" Pack="true" PackagePath=""/>
39+
<None Include="icon.png" Pack="true" PackagePath="\"/>
40+
</ItemGroup>
4141

4242
</Project>

Flagsmith.FlagsmithClient/FlagsmithClient.cs

Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ private void Initialise()
7575
{
7676
if (!_config.EnvironmentKey!.StartsWith("ser."))
7777
{
78-
Console.WriteLine(
79-
"In order to use local evaluation, please generate a server key in the environment settings page."
78+
throw new Exception(
79+
"ValueError: In order to use local evaluation, please generate a server key in the environment settings page."
8080
);
8181
}
8282

@@ -99,85 +99,6 @@ public FlagsmithClient(FlagsmithConfiguration configuration)
9999
Initialise();
100100
}
101101

102-
/// <summary>
103-
/// Create flagsmith client.
104-
/// </summary>
105-
/// <param name="environmentKey">The environment key obtained from Flagsmith interface. Required unless offlineMode is True</param>
106-
/// <param name="apiUrl">Override the URL of the Flagsmith API to communicate with. Required unless offlineMode is True</param>
107-
/// <param name="logger">Provide logger for logging polling info and errors which is only applicable when client side evalution is enabled and analytics errors.</param>
108-
/// <param name="defaultFlagHandler">Callable which will be used in the case where flags cannot be retrieved from the API or a non existent feature is requested.</param>
109-
/// <param name="enableAnalytics">if enabled, sends additional requests to the Flagsmith API to power flag analytics charts.</param>
110-
/// <param name="enableClientSideEvaluation">If using local evaluation, specify the interval period between refreshes of local environment data.</param>
111-
/// <param name="environmentRefreshIntervalSeconds"></param>
112-
/// <param name="customHeaders">Additional headers to add to requests made to the Flagsmith API</param>
113-
/// <param name="retries">Total http retries for every failing request before throwing the final error.</param>
114-
/// <param name="requestTimeout">Number of seconds to wait for a request to complete before terminating the request</param>
115-
/// <param name="httpClient">Http client used for flagsmith-API requests</param>
116-
/// <param name="cacheConfig">Cache configuration. Example new CacheConfig(true) </param>
117-
/// <param name="OfflineMode">Sets the client into offline mode. Relies on offlineHandler for evaluating flags.</param>
118-
/// <param name="offlineHandler">Offline handler for evaluating flags. Required unless OfflineMode is False.</param>
119-
/// <exception cref="FlagsmithAPIError">
120-
/// Thrown when error occurs during any http request to Flagsmith api.Not applicable for polling or ananlytics.
121-
/// </exception>
122-
/// <exception cref="FlagsmithClientError">
123-
/// A general exception with a error message. Example: Feature not found, etc.
124-
/// </exception>
125-
[Obsolete("Use FlagsmithClient(FlagsmithConfiguration) instead.")]
126-
public FlagsmithClient(
127-
string? environmentKey = null,
128-
string apiUrl = "https://edge.api.flagsmith.com/api/v1/",
129-
ILogger? logger = null,
130-
Func<string, IFlag>? defaultFlagHandler = null,
131-
bool enableAnalytics = false,
132-
bool enableClientSideEvaluation = false,
133-
int environmentRefreshIntervalSeconds = 60,
134-
Dictionary<string, string>? customHeaders = null,
135-
int retries = 1,
136-
double? requestTimeout = null,
137-
HttpClient? httpClient = null,
138-
CacheConfig? cacheConfig = null,
139-
bool offlineMode = false,
140-
BaseOfflineHandler? offlineHandler = null
141-
)
142-
{
143-
_config = new FlagsmithConfiguration
144-
{
145-
EnvironmentKey = environmentKey,
146-
ApiUri = new Uri(apiUrl),
147-
EnvironmentRefreshInterval = TimeSpan.FromSeconds(environmentRefreshIntervalSeconds),
148-
EnableLocalEvaluation = enableClientSideEvaluation,
149-
Logger = logger,
150-
EnableAnalytics = enableAnalytics,
151-
RequestTimeout = requestTimeout,
152-
Retries = retries,
153-
CustomHeaders = customHeaders,
154-
CacheConfig = cacheConfig ?? new CacheConfig(false),
155-
OfflineMode = offlineMode,
156-
OfflineHandler = offlineHandler,
157-
HttpClient = httpClient,
158-
};
159-
// The type of defaultFlagHandler in this constructor is `Func<string, IFlag>?`, but the type of
160-
// IFlagsmithConfiguration.DefaultFlagHandler is `Func<string, Flag>`
161-
if (defaultFlagHandler != null)
162-
{
163-
Flag Handler(string s) => (defaultFlagHandler(s) as Flag)!;
164-
_config.DefaultFlagHandler = Handler;
165-
}
166-
Initialise();
167-
}
168-
169-
/// <summary>
170-
/// <para>Creates a Flagsmith client.</para>
171-
/// <para>Deprecated since 7.1.0. Use <see cref="FlagsmithClient(FlagsmithConfiguration)"/> instead.</para>
172-
/// </summary>
173-
[Obsolete("This constructor is deprecated. Use FlagsmithClient(IFlagsmithConfiguration) instead.")]
174-
public FlagsmithClient(IFlagsmithConfiguration configuration, HttpClient httpClient)
175-
{
176-
_config = (FlagsmithConfiguration)configuration;
177-
_config.HttpClient = httpClient;
178-
Initialise();
179-
}
180-
181102
/// <summary>
182103
/// Get all the default for flags for the current environment.
183104
/// </summary>

Flagsmith.FlagsmithClient/FlagsmithConfiguration.cs

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ public class FlagsmithConfiguration
1111
private static readonly Uri DefaultApiUri = new Uri("https://edge.api.flagsmith.com/api/v1/");
1212
private TimeSpan _timeout;
1313

14-
/// <summary>
15-
/// <para>Override the URL of the Flagsmith API to communicate with.</para>
16-
/// <para>Deprecated since 7.1.0. Use <see cref="ApiUri"/> instead.</para>
17-
/// </summary>
18-
[Obsolete("Use ApiUri instead.")]
19-
public string ApiUrl
20-
{
21-
get => ApiUri.ToString();
22-
set => ApiUri = value.EndsWith("/") ? new Uri(value) : new Uri($"{value}/");
23-
}
24-
2514
/// <summary>
2615
/// Versioned base Flagsmith API URI to use for all requests. Defaults to
2716
/// <c>https://edge.api.flagsmith.com/api/v1/</c>.
@@ -34,43 +23,26 @@ public string ApiUrl
3423
/// </summary>
3524
public string EnvironmentKey { get; set; }
3625

37-
/// <summary>
38-
/// Enables local evaluation of flags.
39-
/// </summary>
40-
[Obsolete("Use EnableLocalEvaluation instead.")]
41-
public bool EnableClientSideEvaluation
42-
{
43-
get => EnableLocalEvaluation;
44-
set => EnableLocalEvaluation = value;
45-
}
46-
4726
/// <summary>
4827
/// Enables local evaluation of flags.
4928
/// </summary>
5029
public bool EnableLocalEvaluation { get; set; }
5130

52-
/// <summary>
53-
/// <para>If using local evaluation, specify the interval period between refreshes of local environment data.</para>
54-
/// <para>Deprecated since 7.1.0. Use <see cref="EnvironmentRefreshInterval"/> instead.</para>
55-
/// </summary>
56-
[Obsolete("Use EnvironmentRefreshInterval instead.")]
57-
public int EnvironmentRefreshIntervalSeconds
58-
{
59-
get => EnvironmentRefreshInterval.Seconds;
60-
set => EnvironmentRefreshInterval = TimeSpan.FromSeconds(value);
61-
}
6231
/// <summary>
6332
/// If using local evaluation, specify the interval period between refreshes of local environment data.
6433
/// </summary>
6534
public TimeSpan EnvironmentRefreshInterval { get; set; } = TimeSpan.FromSeconds(60);
35+
6636
/// <summary>
6737
/// Callable which will be used in the case where flags cannot be retrieved from the API or a non existent feature is requested.
6838
/// </summary>
6939
public Func<string, Flag>? DefaultFlagHandler { get; set; }
40+
7041
/// <summary>
7142
/// Provide logger for logging polling info & errors which is only applicable when client side evalution is enabled and analytics errors.
7243
/// </summary>
7344
public ILogger Logger { get; set; }
45+
7446
/// <summary>
7547
/// if enabled, sends additional requests to the Flagsmith API to power flag analytics charts.
7648
/// </summary>
@@ -89,6 +61,7 @@ public Double? RequestTimeout
8961
/// Total http retries for every failing request before throwing the final error.
9062
/// </summary>
9163
public int? Retries { get; set; }
64+
9265
/// <summary>
9366
/// Additional headers to add to requests made to the Flagsmith API
9467
/// </summary>
@@ -113,11 +86,5 @@ public Double? RequestTimeout
11386
/// Http client used for flagsmith-API requests.
11487
/// </summary>
11588
public HttpClient HttpClient { get; set; } = new HttpClient();
116-
117-
[Obsolete("This method will be removed in a future release.")]
118-
public bool IsValid()
119-
{
120-
return !string.IsNullOrEmpty(ApiUri.ToString()) && !string.IsNullOrEmpty(EnvironmentKey);
121-
}
12289
}
12390
}

0 commit comments

Comments
 (0)