From a4ce3d997adcd71dcd59eca2d8c14b78ac8b7ff9 Mon Sep 17 00:00:00 2001 From: Carolyn Van Slyck Date: Tue, 20 Sep 2016 10:30:54 -0500 Subject: [PATCH 1/2] Deserialize vanilla openstack token with preconfigured jsonserializer The default json.net serializer will helpfully reformat strings that appear to be date time strings for you, even when the destination property is a string. Use the preconfigured jsonserializer which has this disabled, to preserve the expires string as-is. --- .../Providers/OpenStackIdentityProvider.cs | 8 +++++--- src/corelib/OpenStackNet.cs | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/corelib/Core/Providers/OpenStackIdentityProvider.cs b/src/corelib/Core/Providers/OpenStackIdentityProvider.cs index d5f48a6c1..ee08b700d 100644 --- a/src/corelib/Core/Providers/OpenStackIdentityProvider.cs +++ b/src/corelib/Core/Providers/OpenStackIdentityProvider.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Newtonsoft.Json; using OpenStack; using OpenStack.Authentication; @@ -109,11 +110,12 @@ public override UserAccess GetUserAccess(CloudIdentity identity, bool forceCache if (response == null || response.Data == null) return null; - JToken userAccessObject = response.Data["access"]; - if (userAccessObject == null) + // The defalut json serialization is helpfully formatting the expires date string. Use our custom serializer for this part to prevent chaos of timezone proportions. + var rawJson = response.Data["access"]?.ToString(Formatting.None); + if (rawJson == null) return null; - UserAccess access = userAccessObject.ToObject(); + UserAccess access = OpenStackNet.Deserialize(rawJson); if (access == null || access.Token == null) return null; diff --git a/src/corelib/OpenStackNet.cs b/src/corelib/OpenStackNet.cs index 5f2fb985d..a8eff122f 100644 --- a/src/corelib/OpenStackNet.cs +++ b/src/corelib/OpenStackNet.cs @@ -89,6 +89,26 @@ public static void ResetDefaults() } } + /// + /// Deserializes an object from a json string representation. + /// + /// The object type. + /// The json string. + public static T Deserialize(string json) + { + return Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + } + + /// + /// Serializes an object to a json string representation + /// + /// The object. + /// The json string representation of the object. + public static string Serialize(object obj) + { + return Configuration.FlurlHttpSettings.JsonSerializer.Serialize(obj); + } + /// /// Provides global point for programmatically configuraing tracing /// From f3fb8f10048ed25388daab2b6b054f903112cc76 Mon Sep 17 00:00:00 2001 From: Carolyn Van Slyck Date: Tue, 20 Sep 2016 10:31:38 -0500 Subject: [PATCH 2/2] Make it easier to get at the good jsonserializer --- .../v1/ServiceOperationFailedException.cs | 4 ++-- src/corelib/Testing/HttpTest.cs | 2 +- src/testing/unit/Compute/v2_1/KeyPairTests.cs | 2 +- .../unit/Compute/v2_1/SecurityGroupTests.cs | 2 +- src/testing/unit/Compute/v2_1/ServerTests.cs | 4 ++-- src/testing/unit/Compute/v2_1/VolumeTests.cs | 2 +- .../v1/ServiceCacheTests.cs | 6 +++--- .../ContentDeliveryNetworks/v1/ServiceTests.cs | 8 ++++---- src/testing/unit/IdentifierTests.cs | 8 ++++---- .../Networking/v2/DHCPOptionConverterTests.cs | 8 ++++---- .../unit/Serialization/EmptyEnumerableTests.cs | 6 +++--- .../Serialization/RootWrapperConverterTests.cs | 16 ++++++++-------- .../Serialization/TolerantEnumConverterTests.cs | 10 +++++----- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/corelib/ContentDeliveryNetworks/v1/ServiceOperationFailedException.cs b/src/corelib/ContentDeliveryNetworks/v1/ServiceOperationFailedException.cs index 689de1c47..ba8f35596 100644 --- a/src/corelib/ContentDeliveryNetworks/v1/ServiceOperationFailedException.cs +++ b/src/corelib/ContentDeliveryNetworks/v1/ServiceOperationFailedException.cs @@ -27,7 +27,7 @@ public ServiceOperationFailedException(IEnumerable errors) /// The that contains contextual information about the source or destination. private ServiceOperationFailedException(SerializationInfo info, StreamingContext context) : base(info, context) { - Errors = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize>(info.GetString("service_errors")); + Errors = OpenStackNet.Deserialize>(info.GetString("service_errors")); } /// @@ -48,7 +48,7 @@ private ServiceOperationFailedException(SerializationInfo info, StreamingContext public override void GetObjectData(SerializationInfo info, StreamingContext context) { // ReSharper disable once ExceptionNotDocumented - info.AddValue("service_errors", OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(Errors)); + info.AddValue("service_errors", OpenStackNet.Serialize(Errors)); base.GetObjectData(info, context); } } diff --git a/src/corelib/Testing/HttpTest.cs b/src/corelib/Testing/HttpTest.cs index 7d3d058ac..f26328914 100644 --- a/src/corelib/Testing/HttpTest.cs +++ b/src/corelib/Testing/HttpTest.cs @@ -54,7 +54,7 @@ private void SetTestMode(OpenStackNetConfigurationOptions options) ResponseQueue.Enqueue(new HttpResponseMessage { StatusCode = (HttpStatusCode)status, - Content = new CapturedJsonContent(OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(data)) + Content = new CapturedJsonContent(OpenStackNet.Serialize(data)) }); return this; } diff --git a/src/testing/unit/Compute/v2_1/KeyPairTests.cs b/src/testing/unit/Compute/v2_1/KeyPairTests.cs index 6f880b3a3..69e391475 100644 --- a/src/testing/unit/Compute/v2_1/KeyPairTests.cs +++ b/src/testing/unit/Compute/v2_1/KeyPairTests.cs @@ -43,7 +43,7 @@ public void DeserializeKeyPairCollection() ] }").ToString(); - var results = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var results = OpenStackNet.Deserialize(json); Assert.NotNull(results); Assert.Equal(2, results.Count()); var result = results.First(); diff --git a/src/testing/unit/Compute/v2_1/SecurityGroupTests.cs b/src/testing/unit/Compute/v2_1/SecurityGroupTests.cs index 77e4a123c..b67deee14 100644 --- a/src/testing/unit/Compute/v2_1/SecurityGroupTests.cs +++ b/src/testing/unit/Compute/v2_1/SecurityGroupTests.cs @@ -98,7 +98,7 @@ public void DeserializeSecurityGroupRule() }, 'id': '55d75417-37df-48e2-96aa-20ba53a82900' }}"; - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(JObject.Parse(json).ToString()); + var result = OpenStackNet.Deserialize(JObject.Parse(json).ToString()); Assert.Equal("0.0.0.0 / 24", result.CIDR); } diff --git a/src/testing/unit/Compute/v2_1/ServerTests.cs b/src/testing/unit/Compute/v2_1/ServerTests.cs index ab673c0c1..3b926a19b 100644 --- a/src/testing/unit/Compute/v2_1/ServerTests.cs +++ b/src/testing/unit/Compute/v2_1/ServerTests.cs @@ -29,7 +29,7 @@ public void SerializeServerWithSchedulerHints() server.SchedulerHints = new SchedulerHints(); server.SchedulerHints.Add("group", "groupId"); - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(server); + var json = OpenStackNet.Serialize(server); Assert.Equal(expectedJson, json); } @@ -40,7 +40,7 @@ public void SerializeServerWithoutSchedulerHints() .ToString(Formatting.None); var server = new ServerCreateDefinition("name", Guid.Empty, Guid.Empty); - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(server); + var json = OpenStackNet.Serialize(server); Assert.Equal(expectedJson, json); } diff --git a/src/testing/unit/Compute/v2_1/VolumeTests.cs b/src/testing/unit/Compute/v2_1/VolumeTests.cs index 7cda497b5..bcfca48fc 100644 --- a/src/testing/unit/Compute/v2_1/VolumeTests.cs +++ b/src/testing/unit/Compute/v2_1/VolumeTests.cs @@ -24,7 +24,7 @@ public VolumeTests() public void DeserializeVolumeWithEmptyAttachment() { var json = JObject.Parse(@"{'volume': {'attachments': [{}]}}").ToString(); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var result = OpenStackNet.Deserialize(json); Assert.Empty(result.Attachments); } diff --git a/src/testing/unit/ContentDeliveryNetworks/v1/ServiceCacheTests.cs b/src/testing/unit/ContentDeliveryNetworks/v1/ServiceCacheTests.cs index f2cb8ce49..696b31ead 100644 --- a/src/testing/unit/ContentDeliveryNetworks/v1/ServiceCacheTests.cs +++ b/src/testing/unit/ContentDeliveryNetworks/v1/ServiceCacheTests.cs @@ -12,7 +12,7 @@ public void SerializeTimeToLiveToSeconds() { var cache = new ServiceCache("cache", TimeSpan.FromSeconds(60)); - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(cache); + var json = OpenStackNet.Serialize(cache); var result = JObject.Parse(json); Assert.Equal(60, result.Value("ttl")); @@ -22,9 +22,9 @@ public void SerializeTimeToLiveToSeconds() public void DeserializeTimeToLiveFromSeconds() { var cache = new ServiceCache("cache", TimeSpan.FromSeconds(60)); - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(cache); + var json = OpenStackNet.Serialize(cache); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var result = OpenStackNet.Deserialize(json); Assert.Equal(60, result.TimeToLive.TotalSeconds); } diff --git a/src/testing/unit/ContentDeliveryNetworks/v1/ServiceTests.cs b/src/testing/unit/ContentDeliveryNetworks/v1/ServiceTests.cs index 8295f7255..f1c75a469 100644 --- a/src/testing/unit/ContentDeliveryNetworks/v1/ServiceTests.cs +++ b/src/testing/unit/ContentDeliveryNetworks/v1/ServiceTests.cs @@ -32,11 +32,11 @@ public void SerializeServiceCollection() Items = {new Service {Id = "service-id"}}, Links = {new PageLink("next", "http://api.com/next")} }; - string json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(services); + string json = OpenStackNet.Serialize(services); Assert.Contains("\"services\"", json); Assert.DoesNotContain("\"service\"", json); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var result = OpenStackNet.Deserialize(json); Assert.NotNull(result); Assert.Equal(1, result.Count()); Assert.Equal(1, result.Items.Count()); @@ -48,9 +48,9 @@ public void SerializeServiceCollection() public void SerializePageLink() { var link = new PageLink("next", "http://api.com/next"); - string json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(link); + string json = OpenStackNet.Serialize(link); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var result = OpenStackNet.Deserialize(json); Assert.NotNull(result); Assert.True(result.IsNextPage); } diff --git a/src/testing/unit/IdentifierTests.cs b/src/testing/unit/IdentifierTests.cs index d96b3d361..9503d28f9 100644 --- a/src/testing/unit/IdentifierTests.cs +++ b/src/testing/unit/IdentifierTests.cs @@ -17,7 +17,7 @@ public void Serialize() var rawId = Guid.NewGuid(); var id = (Identifier)rawId; - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(id); + var result = OpenStackNet.Serialize(id); Assert.Equal(string.Format("\"{0}\"", rawId.ToString("D")), result); } @@ -27,7 +27,7 @@ public void Serialize_WithinAClass() { var thing = new Thing {Id = Guid.NewGuid()}; - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(thing); + var result = OpenStackNet.Serialize(thing); Assert.Equal(string.Format("{{\"Id\":\"{0}\"}}", thing.Id), result); } @@ -37,8 +37,8 @@ public void Deserialize() { var id = new Identifier(Guid.NewGuid()); - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(id); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var json = OpenStackNet.Serialize(id); + var result = OpenStackNet.Deserialize(json); Assert.Equal(id, result); } diff --git a/src/testing/unit/Networking/v2/DHCPOptionConverterTests.cs b/src/testing/unit/Networking/v2/DHCPOptionConverterTests.cs index c20ae1e32..a73f128e8 100644 --- a/src/testing/unit/Networking/v2/DHCPOptionConverterTests.cs +++ b/src/testing/unit/Networking/v2/DHCPOptionConverterTests.cs @@ -19,7 +19,7 @@ public void Serialize() } }; - string result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(input); + string result = OpenStackNet.Serialize(input); string expectedJson = JObject.Parse("{'port':{'extra_dhcp_opts':[{'opt_name':'a','opt_value':'stuff'},{'opt_name':'b','opt_value':'things'}]}}").ToString(Formatting.None); Assert.Equal(expectedJson, result); @@ -30,7 +30,7 @@ public void Deserialize() { string json = JObject.Parse("{'port':{'extra_dhcp_opts':[{'opt_name':'a','opt_value':'stuff'},{'opt_name':'b','opt_value':'things'}]}}").ToString(Formatting.None); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json).DHCPOptions; + var result = OpenStackNet.Deserialize(json).DHCPOptions; Assert.NotNull(result); Assert.Equal(2, result.Count); @@ -52,8 +52,8 @@ public void OpenStackNet_UsesDHCPOptionConverter() } }; - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(port); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var json = OpenStackNet.Serialize(port); + var result = OpenStackNet.Deserialize(json); Assert.NotNull(result.DHCPOptions); Assert.Equal(1, result.DHCPOptions.Count); diff --git a/src/testing/unit/Serialization/EmptyEnumerableTests.cs b/src/testing/unit/Serialization/EmptyEnumerableTests.cs index 98aaca6af..86f10021c 100644 --- a/src/testing/unit/Serialization/EmptyEnumerableTests.cs +++ b/src/testing/unit/Serialization/EmptyEnumerableTests.cs @@ -21,10 +21,10 @@ public ExampleThing() public void WhenDeserializingNullCollection_ItShouldUseAnEmptyCollection() { var thing = new ExampleThing{Messages = null}; - string json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(thing); + string json = OpenStackNet.Serialize(thing); Assert.DoesNotContain("messages", json); - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var result = OpenStackNet.Deserialize(json); Assert.NotNull(result.Messages); Assert.Empty(result.Messages); @@ -35,7 +35,7 @@ public void WhenSerializingEmptyCollection_ItShouldBeIgnored() { var thing = new ExampleThing { Messages = new List() }; - string json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(thing); + string json = OpenStackNet.Serialize(thing); Assert.DoesNotContain("messages", json); } diff --git a/src/testing/unit/Serialization/RootWrapperConverterTests.cs b/src/testing/unit/Serialization/RootWrapperConverterTests.cs index a88a25c71..155a11e1c 100644 --- a/src/testing/unit/Serialization/RootWrapperConverterTests.cs +++ b/src/testing/unit/Serialization/RootWrapperConverterTests.cs @@ -23,7 +23,7 @@ class ThingCollection : List [Fact] public void Serialize() { - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(new Thing()); + var json = OpenStackNet.Serialize(new Thing()); var jsonObj = JObject.Parse(json); JProperty rootProperty = jsonObj.Properties().FirstOrDefault(); @@ -34,15 +34,15 @@ public void Serialize() [Fact] public void Deserialize() { - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(new Thing {Id = "thing-id"}); - var thing = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var json = OpenStackNet.Serialize(new Thing {Id = "thing-id"}); + var thing = OpenStackNet.Deserialize(json); Assert.Equal("thing-id", thing.Id); } [Fact] public void SerializeWhenNotRoot() { - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(new List{ new Thing() }); + var json = OpenStackNet.Serialize(new List{ new Thing() }); Assert.DoesNotContain("\"thing\"", json); } @@ -50,7 +50,7 @@ public void SerializeWhenNotRoot() [Fact] public void SerializeWhenNested() { - var json = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Serialize(new ThingCollection { new Thing() }); + var json = OpenStackNet.Serialize(new ThingCollection { new Thing() }); Assert.DoesNotContain("\"thing\"", json); } @@ -59,7 +59,7 @@ public void SerializeWhenNested() public void DeserializeWhenNotRoot() { var json = JArray.Parse("[{'id':'thing-id'}]").ToString(); - var things = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize>(json); + var things = OpenStackNet.Deserialize>(json); Assert.Equal(1, things.Count); Assert.Equal("thing-id", things[0].Id); } @@ -68,7 +68,7 @@ public void DeserializeWhenNotRoot() public void DeserializeWhenNested() { var json = JObject.Parse("{'things':[{'id':'thing-id'}]}").ToString(); - var things = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var things = OpenStackNet.Deserialize(json); Assert.NotNull(things); Assert.Equal(1, things.Count); Assert.Equal("thing-id", things[0].Id); @@ -78,7 +78,7 @@ public void DeserializeWhenNested() public void ShouldIgnoreUnexpectedRootProperties() { var json = JObject.Parse("{'links': [{'name': 'next', 'link': 'http://nextlink'}], 'thing': {'id': 'thing-id'}}").ToString(); - var thing = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize(json); + var thing = OpenStackNet.Deserialize(json); Assert.NotNull(thing); Assert.Equal("thing-id", thing.Id); } diff --git a/src/testing/unit/Serialization/TolerantEnumConverterTests.cs b/src/testing/unit/Serialization/TolerantEnumConverterTests.cs index 46ab46d0b..dc8967f2a 100644 --- a/src/testing/unit/Serialization/TolerantEnumConverterTests.cs +++ b/src/testing/unit/Serialization/TolerantEnumConverterTests.cs @@ -25,7 +25,7 @@ enum StuffStatus [Fact] public void WhenValueIsRecognized_MatchToValue() { - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize("\"ACTIVE\""); + var result = OpenStackNet.Deserialize("\"ACTIVE\""); Assert.Equal(ThingStatus.Active, result); } @@ -33,7 +33,7 @@ public void WhenValueIsRecognized_MatchToValue() [Fact] public void WhenAttributedValueIsRecognized_MatchToValue() { - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize("\"REMOVE_FAILED\""); + var result = OpenStackNet.Deserialize("\"REMOVE_FAILED\""); Assert.Equal(ThingStatus.RemoveFailed, result); } @@ -41,7 +41,7 @@ public void WhenAttributedValueIsRecognized_MatchToValue() [Fact] public void WhenValueIsUnrecognized_MatchToUnknownValue() { - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize("\"bad-enum-value\""); + var result = OpenStackNet.Deserialize("\"bad-enum-value\""); Assert.Equal(ThingStatus.Unknown, result); } @@ -49,7 +49,7 @@ public void WhenValueIsUnrecognized_MatchToUnknownValue() [Fact] public void WhenValueIsUnrecognized_AndUnknownIsNotPresent_MatchToFirstValue() { - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize("\"bad-enum-value\""); + var result = OpenStackNet.Deserialize("\"bad-enum-value\""); Assert.Equal(StuffStatus.Missing, result); } @@ -57,7 +57,7 @@ public void WhenValueIsUnrecognized_AndUnknownIsNotPresent_MatchToFirstValue() [Fact] public void WhenValueIsUnrecognized_AndDestinationIsNullable_UseNull() { - var result = OpenStackNet.Configuration.FlurlHttpSettings.JsonSerializer.Deserialize("\"bad-enum-value\""); + var result = OpenStackNet.Deserialize("\"bad-enum-value\""); Assert.Null(result); }