Skip to content

Commit f64e7b6

Browse files
committed
Merge pull request #42 from carolynvs/#40-configure-rackspacenet
Improve RackspaceNet Configuration
2 parents 01be92f + 5ebd444 commit f64e7b6

File tree

7 files changed

+168
-12
lines changed

7 files changed

+168
-12
lines changed

src/Rackspace/CloudNetworks/v2/CloudNetworkService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class CloudNetworkService
2424
/// <param name="region">The region.</param>
2525
public CloudNetworkService(OpenStack.Authentication.IAuthenticationProvider authenticationProvider, string region)
2626
{
27+
RackspaceNet.Configure();
2728
_networkingApiBuilder = new NetworkingApiBuilder(ServiceType.CloudNetworks, authenticationProvider, region);
2829
}
2930

src/Rackspace/RackConnect/v3/RackConnectService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public RackConnectService(IAuthenticationProvider authenticationProvider, string
3737
if (string.IsNullOrEmpty(region))
3838
throw new ArgumentException("region cannot be null or empty", "region");
3939

40+
RackspaceNet.Configure();
41+
4042
_authenticationProvider = authenticationProvider;
4143
_urlBuilder = new ServiceUrlBuilder(ServiceType.RackConnect, authenticationProvider, region);
4244
}

src/Rackspace/RackspaceNet.cs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
using System;
22
using System.Diagnostics;
33
using System.Extensions;
4-
using System.Linq;
54
using System.Net.Http.Headers;
65
using Flurl.Http;
76
using Flurl.Http.Configuration;
8-
using net.openstack.Core;
97
using Newtonsoft.Json;
108
using OpenStack;
119

@@ -23,6 +21,7 @@ public static class RackspaceNet
2321
/// </summary>
2422
public static readonly RackspaceNetConfigurationOptions Configuration = new RackspaceNetConfigurationOptions();
2523
private static readonly object ConfigureLock = new object();
24+
private static bool _isConfigured;
2625

2726
/// <summary>
2827
/// Provides thread-safe accesss to Rackspace.NET's global configuration options.
@@ -35,16 +34,37 @@ public static class RackspaceNet
3534
/// <param name="configure">Additional configuration of Rackspace.NET's global settings.</param>
3635
public static void Configure(Action<FlurlHttpConfigurationOptions> configureFlurl = null, Action<JsonSerializerSettings> configureJson = null, Action<RackspaceNetConfigurationOptions> configure = null)
3736
{
38-
if (configure != null)
39-
lock (ConfigureLock) { configure(Configuration); }
37+
lock (ConfigureLock)
38+
{
39+
if (_isConfigured)
40+
return;
41+
42+
OpenStackNet.Configure(configureFlurl, configureJson);
43+
44+
configure?.Invoke(Configuration);
45+
Configuration.Apply(OpenStackNet.Configuration);
4046

41-
Action<OpenStackNetConfigurationOptions> configureOpenStackNet = options =>
47+
_isConfigured = true;
48+
}
49+
}
50+
51+
/// <summary>
52+
/// Resets all configuration (Rackspace.NET, OpenStack.NET, Flurl and Json.NET) so that <see cref="Configure"/> can be called again.
53+
/// </summary>
54+
public static void ResetDefaults()
55+
{
56+
lock (ConfigureLock)
4257
{
43-
Configuration.Apply(options);
44-
};
45-
OpenStackNet.Configure(configureFlurl, configureJson, configureOpenStackNet);
58+
if (!_isConfigured)
59+
return;
60+
61+
Configuration.ResetDefaults();
62+
OpenStackNet.ResetDefaults();
63+
64+
_isConfigured = false;
65+
}
4666
}
47-
67+
4868
/// <inheritdoc cref="OpenStack.OpenStackNet.Tracing" />
4969
public static class Tracing
5070
{
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using Flurl.Http;
3+
using Xunit;
4+
5+
namespace Rackspace.CloudNetworks.v2
6+
{
7+
public class CloudNetworkServiceTests : IDisposable
8+
{
9+
public CloudNetworkServiceTests()
10+
{
11+
RackspaceNet.ResetDefaults();
12+
}
13+
14+
public void Dispose()
15+
{
16+
RackspaceNet.ResetDefaults();
17+
}
18+
19+
[Fact]
20+
public void RackspaceNetIsConfiguredByService()
21+
{
22+
Assert.Null(FlurlHttp.Configuration.BeforeCall);
23+
new CloudNetworkService(Stubs.IdentityService, "region");
24+
Assert.NotNull(FlurlHttp.Configuration.BeforeCall);
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using Flurl.Http;
3+
using Xunit;
4+
5+
namespace Rackspace.RackConnect.v3
6+
{
7+
public class RackConnectServiceTests : IDisposable
8+
{
9+
public RackConnectServiceTests()
10+
{
11+
RackspaceNet.ResetDefaults();
12+
}
13+
14+
public void Dispose()
15+
{
16+
RackspaceNet.ResetDefaults();
17+
}
18+
19+
[Fact]
20+
public void RackspaceNetIsConfiguredByService()
21+
{
22+
Assert.Null(FlurlHttp.Configuration.BeforeCall);
23+
new RackConnectService(Stubs.IdentityService, "region");
24+
Assert.NotNull(FlurlHttp.Configuration.BeforeCall);
25+
}
26+
}
27+
}

test/Rackspace.UnitTests/Rackspace.UnitTests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@
7979
</Reference>
8080
</ItemGroup>
8181
<ItemGroup>
82+
<Compile Include="CloudNetworks\v2\CloudNetworkServiceTests.cs" />
8283
<Compile Include="Properties\AssemblyInfo.cs" />
8384
<Compile Include="CloudNetworks\v2\NetworkTests.cs" />
8485
<Compile Include="CloudNetworks\v2\PortTests.cs" />
8586
<Compile Include="CloudNetworks\v2\SubnetTests.cs" />
8687
<Compile Include="IdentifierTests.cs" />
88+
<Compile Include="RackConnect\v3\RackConnectServiceTests.cs" />
8789
<Compile Include="RackConnect\v3\NetworkTests.cs" />
8890
<Compile Include="RackConnect\v3\PublicIPTests.cs" />
8991
<Compile Include="RackspaceNetTests.cs" />

test/Rackspace.UnitTests/RackspaceNetTests.cs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,77 @@
11
using System;
22
using System.Net.Http.Headers;
3+
using System.Text.RegularExpressions;
4+
using System.Threading.Tasks;
35
using Flurl.Http;
6+
using OpenStack;
47
using Rackspace.Testing;
58
using Xunit;
69

710
namespace Rackspace
811
{
912
public class RackspaceNetTests : IDisposable
1013
{
14+
public RackspaceNetTests()
15+
{
16+
RackspaceNet.ResetDefaults();
17+
}
18+
1119
public void Dispose()
1220
{
13-
RackspaceNet.Configuration.ResetDefaults();
21+
RackspaceNet.ResetDefaults();
22+
}
23+
24+
[Fact]
25+
public async Task UseBothOpenStackAndRackspace_OpenStackConfiguredFirst()
26+
{
27+
using (var httpTest = new HttpTest())
28+
{
29+
OpenStackNet.Configure();
30+
RackspaceNet.Configure();
31+
32+
await "http://api.com".GetAsync();
33+
34+
var userAgent = httpTest.CallLog[0].Request.Headers.UserAgent.ToString();
35+
36+
var rackspaceMatches = new Regex("rackspace").Matches(userAgent);
37+
Assert.Equal(1, rackspaceMatches.Count);
38+
39+
var openstackMatches = new Regex("openstack").Matches(userAgent);
40+
Assert.Equal(1, openstackMatches.Count);
41+
}
42+
}
43+
44+
[Fact]
45+
public async Task UseBothOpenStackAndRackspace_RackspaceConfiguredFirst()
46+
{
47+
using (var httpTest = new HttpTest())
48+
{
49+
RackspaceNet.Configure();
50+
OpenStackNet.Configure();
51+
52+
await "http://api.com".GetAsync();
53+
54+
var userAgent = httpTest.CallLog[0].Request.Headers.UserAgent.ToString();
55+
56+
var rackspaceMatches = new Regex("rackspace").Matches(userAgent);
57+
Assert.Equal(1, rackspaceMatches.Count);
58+
59+
var openstackMatches = new Regex("openstack").Matches(userAgent);
60+
Assert.Equal(1, openstackMatches.Count);
61+
}
62+
}
63+
64+
[Fact]
65+
public void ResetDefaults_ResetsFlurlConfiguration()
66+
{
67+
RackspaceNet.Configure();
68+
Assert.NotNull(FlurlHttp.Configuration.BeforeCall);
69+
RackspaceNet.ResetDefaults();
70+
Assert.Null(FlurlHttp.Configuration.BeforeCall);
1471
}
1572

1673
[Fact]
17-
public async void UserAgentTest()
74+
public async Task UserAgentTest()
1875
{
1976
using (var httpTest = new HttpTest())
2077
{
@@ -29,7 +86,27 @@ public async void UserAgentTest()
2986
}
3087

3188
[Fact]
32-
public async void UserAgentWithApplicationSuffixTest()
89+
public async Task UserAgentOnlyListedOnceTest()
90+
{
91+
using (var httpTest = new HttpTest())
92+
{
93+
RackspaceNet.Configure();
94+
RackspaceNet.Configure();
95+
96+
await "http://api.com".GetAsync();
97+
98+
var userAgent = httpTest.CallLog[0].Request.Headers.UserAgent.ToString();
99+
100+
var rackspaceMatches = new Regex("rackspace").Matches(userAgent);
101+
Assert.Equal(1, rackspaceMatches.Count);
102+
103+
var openstackMatches = new Regex("openstack").Matches(userAgent);
104+
Assert.Equal(1, openstackMatches.Count);
105+
}
106+
}
107+
108+
[Fact]
109+
public async Task UserAgentWithApplicationSuffixTest()
33110
{
34111
using (var httpTest = new HttpTest())
35112
{

0 commit comments

Comments
 (0)