Skip to content

Commit 38b3df3

Browse files
msohailhussainMichael Ng
authored andcommitted
3.2.x release (#177)
1 parent a2727e9 commit 38b3df3

File tree

13 files changed

+191
-37
lines changed

13 files changed

+191
-37
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## 3.2.0
2+
July 22nd, 2019
3+
4+
### New Features:
5+
* Added support for automatic datafile management via `HttpProjectConfigManager` for framework 4.0 or above:
6+
* The [`HttpProjectConfigManager`](https://github.com/optimizely/csharp-sdk/blob/master/OptimizelySDK/Config/HttpProjectConfigManager.cs) is an implementation of the abstract
7+
[`PollingProjectConfigManager`](https://github.com/optimizely/csharp-sdk/blob/master/OptimizelySDK/Config/PollingProjectConfigManager.cs) class.
8+
- Users must first build the `HttpProjectConfigManager` with an SDK key and then and provide that instance to the `Optimizely`.
9+
- An initial datafile can be provided to the `HttpProjectConfigManager` to bootstrap before making http requests for the hosted datafile.
10+
- Requests for the datafile are made in a separate thread and are scheduled with fixed delay.
11+
- Configuration updates can be subscribed to via the NotificationCenter built with the `HttpProjectConfigManager`.
12+
- `Optimizely` instance must be disposed after the use or `HttpProjectConfigManager` must be disposed after the use to release resources.
13+
- The [`OptimizelyFactory`](https://github.com/optimizely/csharp-sdk/blob/master/OptimizelySDK/OptimizelyFactory.cs) provides basic methods for instantiating the Optimizely SDK with a minimal number of parameters. Check [`README.md`](https://github.com/optimizely/csharp-sdk#use-optimizelyfactory) for more details.
14+
115
## 3.1.1
216
June 19th, 2019
317

OptimizelySDK.DemoApp/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@
3737
//
3838
// You can specify all the values or you can default the Revision and Build Numbers
3939
// by using the '*' as shown below:
40-
[assembly: AssemblyVersion("3.1.1.0")]
41-
[assembly: AssemblyFileVersion("3.1.1.0")]
42-
[assembly: AssemblyInformationalVersion("3.1.1")] // Used by Nuget.
40+
[assembly: AssemblyVersion("3.2.0.0")]
41+
[assembly: AssemblyFileVersion("3.2.0.0")]
42+
[assembly: AssemblyInformationalVersion("3.2.0")] // Used by Nuget.

OptimizelySDK.DemoApp/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<package id="murmurhash-signed" version="1.0.2" targetFramework="net45" />
1818
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
1919
<package id="NJsonSchema" version="8.30.6304.31883" targetFramework="net45" />
20-
<package id="Optimizely.SDK" version="3.1.0" targetFramework="net45" />
20+
<package id="Optimizely.SDK" version="3.2.0" targetFramework="net45" />
2121
<package id="popper.js" version="1.12.9" targetFramework="net45" />
2222
<package id="Respond" version="1.2.0" targetFramework="net45" />
2323
<package id="WebGrease" version="1.5.2" targetFramework="net45" />

OptimizelySDK.Net35/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
// You can specify all the values or you can default the Build and Revision Numbers
3939
// by using the '*' as shown below:
4040
// [assembly: AssemblyVersion("1.0.*")]
41-
[assembly: AssemblyVersion("3.1.1.0")]
42-
[assembly: AssemblyFileVersion("3.1.1.0")]
43-
[assembly: AssemblyInformationalVersion("3.1.1")] // Used by Nuget.
41+
[assembly: AssemblyVersion("3.2.0.0")]
42+
[assembly: AssemblyFileVersion("3.2.0.0")]
43+
[assembly: AssemblyInformationalVersion("3.2.0")] // Used by Nuget.

OptimizelySDK.Net40/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
// You can specify all the values or you can default the Build and Revision Numbers
3939
// by using the '*' as shown below:
4040
// [assembly: AssemblyVersion("1.0.*")]
41-
[assembly: AssemblyVersion("3.1.1.0")]
42-
[assembly: AssemblyFileVersion("3.1.1.0")]
43-
[assembly: AssemblyInformationalVersion("3.1.1")] // Used by Nuget.
41+
[assembly: AssemblyVersion("3.2.0.0")]
42+
[assembly: AssemblyFileVersion("3.2.0.0")]
43+
[assembly: AssemblyInformationalVersion("3.2.0")] // Used by Nuget.

OptimizelySDK.NetStandard16/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
// You can specify all the values or you can default the Build and Revision Numbers
3939
// by using the '*' as shown below:
4040
// [assembly: AssemblyVersion("1.0.*")]
41-
[assembly: AssemblyVersion("3.1.1.0")]
42-
[assembly: AssemblyFileVersion("3.1.1.0")]
43-
[assembly: AssemblyInformationalVersion("3.1.1")] // Used by Nuget.
41+
[assembly: AssemblyVersion("3.2.0.0")]
42+
[assembly: AssemblyFileVersion("3.2.0.0")]
43+
[assembly: AssemblyInformationalVersion("3.2.0")] // Used by Nuget.

OptimizelySDK.Package/OptimizelySDK.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package>
33
<metadata>
44
<id>Optimizely.SDK</id>
5-
<version>3.1.0</version>
5+
<version>3.2.0</version>
66
<title>Optimizely C# SDK</title>
77
<authors>Optimizely Development Team</authors>
88
<owners>fullstack.optimizely</owners>

OptimizelySDK.Tests/ConfigTest/HttpProjectConfigManagerTest.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ public void TestHttpConfigManagerDoesNotWaitForTheConfigWhenDeferIsTrue()
130130
.WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
131131
.WithLogger(LoggerMock.Object)
132132
.WithPollingInterval(TimeSpan.FromSeconds(2))
133-
.WithBlockingTimeoutPeriod(TimeSpan.FromSeconds(0))
133+
// negligible timeout
134+
.WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(50))
134135
.WithStartByDefault()
135136
.Build(false);
136137

@@ -176,6 +177,52 @@ public void TestHttpConfigManagerDoesNotSendConfigUpdateNotificationWhenDatafile
176177
NotificationCallbackMock.Verify(nc => nc.TestConfigUpdateCallback(), Times.Never);
177178
Assert.NotNull(httpManager.GetConfig()); Assert.NotNull(httpManager.GetConfig());
178179
}
179-
#endregion
180-
}
180+
181+
[Test]
182+
public void TestDefaultBlockingTimeoutWhileProvidingZero()
183+
{
184+
var httpManager = new HttpProjectConfigManager.Builder()
185+
.WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
186+
.WithDatafile(TestData.Datafile)
187+
.WithLogger(LoggerMock.Object)
188+
.WithPollingInterval(TimeSpan.FromMilliseconds(1000))
189+
.WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(0))
190+
.WithStartByDefault(true)
191+
.Build(true);
192+
193+
LoggerMock.Verify(l => l.Log(LogLevel.INFO, $"Blocking timeout is not valid, using default blocking timeout {TimeSpan.FromSeconds(15).TotalMilliseconds}ms"));
194+
}
195+
196+
[Test]
197+
public void TestDefaultPeriodWhileProvidingZero()
198+
{
199+
var httpManager = new HttpProjectConfigManager.Builder()
200+
.WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
201+
.WithDatafile(TestData.Datafile)
202+
.WithLogger(LoggerMock.Object)
203+
.WithPollingInterval(TimeSpan.FromMilliseconds(0))
204+
.WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(1000))
205+
.WithStartByDefault(true)
206+
.Build(true);
207+
208+
LoggerMock.Verify(l => l.Log(LogLevel.INFO, $"Period is not valid for periodic calls, using default period {TimeSpan.FromMinutes(5).TotalMilliseconds}ms"));
209+
}
210+
211+
[Test]
212+
public void TestDefaultPeriodWhileProvidingNegative()
213+
{
214+
var httpManager = new HttpProjectConfigManager.Builder()
215+
.WithSdkKey("QBw9gFM8oTn7ogY9ANCC1z")
216+
.WithDatafile(TestData.Datafile)
217+
.WithLogger(LoggerMock.Object)
218+
.WithPollingInterval(TimeSpan.FromMilliseconds(-1))
219+
.WithBlockingTimeoutPeriod(TimeSpan.FromMilliseconds(1000))
220+
.WithStartByDefault(true)
221+
.Build(true);
222+
223+
LoggerMock.Verify(l => l.Log(LogLevel.INFO, $"Period is not valid for periodic calls, using default period {TimeSpan.FromMinutes(5).TotalMilliseconds}ms"));
224+
}
225+
226+
#endregion
227+
}
181228
}

OptimizelySDK.Tests/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@
3131
//
3232
// You can specify all the values or you can default the Revision and Build Numbers
3333
// by using the '*' as shown below:
34-
[assembly: AssemblyVersion("3.1.1.0")]
35-
[assembly: AssemblyFileVersion("3.1.1.0")]
36-
[assembly: AssemblyInformationalVersion("3.1.1")] // Used by Nuget.
34+
[assembly: AssemblyVersion("3.2.0.0")]
35+
[assembly: AssemblyFileVersion("3.2.0.0")]
36+
[assembly: AssemblyInformationalVersion("3.2.0")] // Used by Nuget.

OptimizelySDK/Config/HttpProjectConfigManager.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,18 @@ protected override ProjectConfig Poll()
122122

123123
public class Builder
124124
{
125+
private const long MAX_MILLISECONDS_LIMIT = 4294967294;
126+
private readonly TimeSpan DEFAULT_PERIOD = TimeSpan.FromMinutes(5);
127+
private readonly TimeSpan DEFAULT_BLOCKINGOUT_PERIOD = TimeSpan.FromSeconds(15);
128+
125129
private string Datafile;
126130
private string SdkKey;
127131
private string Url;
128132
private string Format = "https://cdn.optimizely.com/datafiles/{0}.json";
129133
private ILogger Logger;
130134
private IErrorHandler ErrorHandler;
131-
private TimeSpan Period = TimeSpan.FromMinutes(5);
132-
private TimeSpan BlockingTimeoutSpan = TimeSpan.FromSeconds(15);
135+
private TimeSpan Period;
136+
private TimeSpan BlockingTimeoutSpan;
133137
private bool AutoUpdate = true;
134138
private bool StartByDefault;
135139
private NotificationCenter NotificationCenter;
@@ -143,42 +147,49 @@ public Builder WithBlockingTimeoutPeriod(TimeSpan blockingTimeoutSpan)
143147
public Builder WithDatafile(string datafile)
144148
{
145149
Datafile = datafile;
150+
146151
return this;
147152
}
148153

149154
public Builder WithSdkKey(string sdkKey)
150155
{
151156
SdkKey = sdkKey;
157+
152158
return this;
153159
}
154160

155161
public Builder WithUrl(string url)
156162
{
157163
Url = url;
164+
158165
return this;
159166
}
160167

161168
public Builder WithPollingInterval(TimeSpan period)
162-
{
169+
{
163170
Period = period;
171+
164172
return this;
165173
}
166174

167175
public Builder WithFormat(string format)
168176
{
169177
Format = format;
178+
170179
return this;
171180
}
172181

173182
public Builder WithLogger(ILogger logger)
174183
{
175184
Logger = logger;
185+
176186
return this;
177187
}
178188

179189
public Builder WithErrorHandler(IErrorHandler errorHandler)
180190
{
181191
ErrorHandler = errorHandler;
192+
182193
return this;
183194
}
184195

@@ -222,20 +233,35 @@ public HttpProjectConfigManager Build()
222233
public HttpProjectConfigManager Build(bool defer)
223234
{
224235
HttpProjectConfigManager configManager = null;
236+
225237
if (Logger == null)
226238
Logger = new DefaultLogger();
227239

240+
if (ErrorHandler == null)
241+
ErrorHandler = new DefaultErrorHandler();
242+
228243
if (string.IsNullOrEmpty(Url) && string.IsNullOrEmpty(SdkKey))
229244
{
230-
ErrorHandler.HandleError(new Exception("SdkKey cannot be null"));
231-
throw new Exception("SdkKey cannot be null");
245+
ErrorHandler.HandleError(new Exception("SdkKey cannot be null"));
232246
}
233247
else if (!string.IsNullOrEmpty(SdkKey))
234248
{
235249
Url = string.Format(Format, SdkKey);
236250
}
251+
252+
if (Period.TotalMilliseconds <= 0 || Period.TotalMilliseconds > MAX_MILLISECONDS_LIMIT) {
253+
Logger.Log(LogLevel.INFO, $"Period is not valid for periodic calls, using default period {DEFAULT_PERIOD.TotalMilliseconds}ms");
254+
Period = DEFAULT_PERIOD;
255+
}
237256

238257

258+
if (BlockingTimeoutSpan.TotalMilliseconds <= 0 || BlockingTimeoutSpan.TotalMilliseconds > MAX_MILLISECONDS_LIMIT) {
259+
Logger.Log(LogLevel.INFO, $"Blocking timeout is not valid, using default blocking timeout {DEFAULT_BLOCKINGOUT_PERIOD.TotalMilliseconds}ms");
260+
BlockingTimeoutSpan = DEFAULT_BLOCKINGOUT_PERIOD;
261+
}
262+
263+
264+
239265
configManager = new HttpProjectConfigManager(Period, Url, BlockingTimeoutSpan, AutoUpdate, Logger, ErrorHandler);
240266

241267
if (Datafile != null)

0 commit comments

Comments
 (0)