Skip to content

Commit

Permalink
GenericResource Serialization (#19898)
Browse files Browse the repository at this point in the history
* Resource Serialization

* Plan Serialization

* Divide Plan class

* Divide Resource class

* Update writer

* Update Plan

* TrackedResource Serialization

* Update GenericResource

* Clean Up

* Update GenericResource

* Remove read only

* Update tests
  • Loading branch information
HarveyLink authored Apr 2, 2021
1 parent 6c30766 commit 8724f9d
Show file tree
Hide file tree
Showing 3 changed files with 316 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using Azure.Core;

namespace Azure.ResourceManager.Core
{
/// <summary>
/// A class representing the generic azure resource data model.
/// </summary>
public partial class GenericResourceData : IUtf8JsonSerializable
{
/// <summary>
/// Serialize the input GenericResourceData object.
/// </summary>
/// <param name="writer"> Input Json writer. </param>
void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
{
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}

writer.WriteStartObject();
if (Optional.IsDefined(Kind))
{
writer.WritePropertyName("kind");
writer.WriteStringValue(Kind);
}
if (Optional.IsDefined(Location))
{
writer.WritePropertyName("location");
writer.WriteStringValue(Location.Name);
}
if (Optional.IsDefined(ManagedBy))
{
writer.WritePropertyName("managedBy");
writer.WriteStringValue(ManagedBy);
}
if (Optional.IsDefined(Plan))
{
writer.WritePropertyName("plan");
writer.WriteObjectValue(Plan);
}
if (Optional.IsDefined(Sku))
{
writer.WritePropertyName("sku");
writer.WriteObjectValue(Sku);
}
if (Optional.IsCollectionDefined(Tags))
{
writer.WritePropertyName("tags");
writer.WriteStartObject();
if (Tags != null)
{
foreach (var item in Tags)
{
writer.WritePropertyName(item.Key);
writer.WriteStringValue(item.Value);
}
}
writer.WriteEndObject();
}
writer.WriteEndObject();
}

/// <summary>
/// Deserialize the input Json object.
/// </summary>
/// <param name="element"> The Json object need to be deserialized. </param>
internal static GenericResourceData DeserializeGenericResourceData(JsonElement element)
{
Optional<Plan> plan = default;
Optional<string> kind = default;
Optional<string> managedBy = default;
Optional<Sku> sku = default;
Optional<TenantResourceIdentifier> id = default;
Optional<string> name = default;
Optional<ResourceType> type = default;
Optional<LocationData> location = default;
Optional<IDictionary<string, string>> tags = default;
foreach (JsonProperty property in element.EnumerateObject())
{
if (property.NameEquals("plan"))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
property.ThrowNonNullablePropertyIsNull();
continue;
}
plan = Plan.DeserializePlan(property.Value);
continue;
}
if (property.NameEquals("kind"))
{
kind = property.Value.GetString();
continue;
}
if (property.NameEquals("managedBy"))
{
managedBy = property.Value.GetString();
continue;
}
if (property.NameEquals("sku"))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
property.ThrowNonNullablePropertyIsNull();
continue;
}
sku = Sku.DeserializeSku(property.Value);
continue;
}
if (property.NameEquals("id"))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
property.ThrowNonNullablePropertyIsNull();
continue;
}
id = (Optional<TenantResourceIdentifier>)ResourceIdentifier.Create(property.Value.GetString());
continue;
}
if (property.NameEquals("name"))
{
name = property.Value.GetString();
continue;
}
if (property.NameEquals("type"))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
property.ThrowNonNullablePropertyIsNull();
continue;
}
type = new ResourceType(property.Value.GetString());
continue;
}
if (property.NameEquals("location"))
{
location = (LocationData)property.Value.GetString();
continue;
}
if (property.NameEquals("tags"))
{
if (property.Value.ValueKind == JsonValueKind.Null)
{
property.ThrowNonNullablePropertyIsNull();
continue;
}
Dictionary<string, string> dictionary = new();
foreach (JsonProperty property0 in property.Value.EnumerateObject())
{
dictionary.Add(property0.Name, property0.Value.GetString());
}
tags = dictionary;
continue;
}
}

GenericResourceData data = new(id.Value, location.Value)
{
Plan = plan.Value,
Kind = kind.Value,
ManagedBy = managedBy.Value,
Sku = sku.Value,
Id = id.Value,
Location = location.Value,
};
if (data.Tags != null)
{
data.Tags.Clear();
foreach (KeyValuePair<string, string> item in tags.Value)
{
data.Tags.Add(item);
}
}
return data;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Azure.ResourceManager.Core
/// <summary>
/// A class representing the generic azure resource data model.
/// </summary>
public class GenericResourceData : TrackedResource<TenantResourceIdentifier, ResourceManager.Resources.Models.GenericResource>
public partial class GenericResourceData : TrackedResource<TenantResourceIdentifier, ResourceManager.Resources.Models.GenericResource>
{
/// <summary>
/// Initializes a new instance of the <see cref="GenericResourceData"/> class.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Azure.Core;
using NUnit.Framework;

namespace Azure.ResourceManager.Core.Tests
{
[Parallelizable]
public class GenericResourceDataTests
{
const string Id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1";

[Test]
public void SerializationTestType1()
{
string expected = "{\"properties\":{\"kind\":\"KindForResource\"," +
"\"location\":\"eastus\",\"managedBy\":\"ManagedByForResource\"," +
"\"plan\":{\"name\":\"NameForPlan\",\"publisher\":\"PublisherForPlan\"," +
"\"product\":\"ProductForPlan\",\"promotionCode\":\"PromotionCodeForPlan\"," +
"\"version\":\"VersionForPlan\"},\"sku\":{\"name\":\"NameForSku\",\"tier\":\"TierForSku\"," +
"\"size\":\"SizeForSku\",\"family\":\"FamilyForSku\",\"capacity\":15464547},\"tags\":{}}}";
GenericResourceData data = new(new ResourceGroupResourceIdentifier(Id), LocationData.EastUS)
{
Kind = "KindForResource",
ManagedBy = "ManagedByForResource",
Plan = new Plan("NameForPlan", "PublisherForPlan",
"ProductForPlan", "PromotionCodeForPlan", "VersionForPlan"),
Sku = new Sku("NameForSku", "TierForSku", "FamilyForSku",
"SizeForSku", 15464547),
};
var stream = new MemoryStream();
Utf8JsonWriter writer = new(stream, new JsonWriterOptions());
writer.WriteStartObject();
writer.WritePropertyName("properties");
writer.WriteObjectValue(data);
writer.WriteEndObject();
writer.Flush();
string json = Encoding.UTF8.GetString(stream.ToArray());
Assert.IsTrue(expected.Equals(json));
}

[Test]
public void SerializationTestType2()
{
string expected = "{\"properties\":{\"kind\":\"KindForResource\"," +
"\"managedBy\":\"ManagedByForResource\",\"plan\":{\"name\":\"NameForPlan\"," +
"\"publisher\":\"PublisherForPlan\",\"product\":\"ProductForPlan\"," +
"\"promotionCode\":\"PromotionCodeForPlan\",\"version\":\"VersionForPlan\"}," +
"\"sku\":{\"name\":\"NameForSku\",\"tier\":\"TierForSku\",\"size\":\"SizeForSku\"," +
"\"family\":\"FamilyForSku\",\"capacity\":15464547},\"tags\":{\"key1\":\"value1\"," +
"\"key2\":\"value2\"}}}";
ResourceManager.Resources.Models.GenericResource genericResource = new()
{
Plan = new ResourceManager.Resources.Models.Plan()
{
Name = "NameForPlan",
Publisher = "PublisherForPlan",
Product = "ProductForPlan",
PromotionCode = "PromotionCodeForPlan",
Version = "VersionForPlan",
},
Kind = "KindForResource",
ManagedBy = "ManagedByForResource",
Sku = new ResourceManager.Resources.Models.Sku()
{
Name = "NameForSku",
Capacity = 15464547,
Family = "FamilyForSku",
Model = "ModelForSku",
Size = "SizeForSku",
Tier = "TierForSku",
},
};
genericResource.Tags.Add("key1", "value1");
genericResource.Tags.Add("key2", "value2");
GenericResourceData data = new(genericResource);
var stream = new MemoryStream();
Utf8JsonWriter writer = new(stream, new JsonWriterOptions());
writer.WriteStartObject();
writer.WritePropertyName("properties");
writer.WriteObjectValue(data);
writer.WriteEndObject();
writer.Flush();
string json = Encoding.UTF8.GetString(stream.ToArray());
Assert.IsTrue(expected.Equals(json));
}

[Test]
public void InvalidSerializationTest()
{
string expected = "{\"properties\":{\"location\":\"eastus\",\"tags\":{}}}";
GenericResourceData data = new(new ResourceGroupResourceIdentifier(Id), LocationData.EastUS);
var stream = new MemoryStream();
Utf8JsonWriter writer = new(stream, new JsonWriterOptions());
writer.WriteStartObject();
writer.WritePropertyName("properties");
writer.WriteObjectValue(data);
writer.WriteEndObject();
writer.Flush();
string json = Encoding.UTF8.GetString(stream.ToArray());
Assert.IsTrue(expected.Equals(json));
}

[Test]
public void DeserializationTest()
{
string json = "{\"id\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1\",\"kind\":\"KindForResource\",\"location\":\"eastus\",\"managedBy\":\"ManagedByForResource\",\"name\":\"account1\",\"plan\":{\"name\":\"NameForPlan\",\"publisher\":\"PublisherForPlan\",\"product\":\"ProductForPlan\",\"promotionCode\":\"PromotionCodeForPlan\",\"version\":\"VersionForPlan\"},\"sku\":{\"name\":\"NameForSku\",\"tier\":\"TierForSku\",\"size\":\"SizeForSku\",\"family\":\"FamilyForSku\",\"capacity\":15464547},\"tags\":{},\"type\":\"Microsoft.ClassicStorage/storageAccounts\"}";
JsonElement element = JsonDocument.Parse(json).RootElement;
GenericResourceData data = GenericResourceData.DeserializeGenericResourceData(element);
Assert.IsTrue(data.Name.Equals("account1"));
Assert.IsTrue(data.Location == LocationData.EastUS);
Assert.IsTrue(data.Plan.PromotionCode.Equals("PromotionCodeForPlan"));
}

[Test]
public void InvalidDeserializationTest()
{
string json = "{\"notId\":\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1\",\"location\":\"eastus\",\"managedBy\":\"ManagedByForResource\",\"name\":\"account1\",\"plan\":{\"name\":\"NameForPlan\",\"publisher\":\"PublisherForPlan\",\"product\":\"ProductForPlan\",\"promotionCode\":\"PromotionCodeForPlan\",\"version\":\"VersionForPlan\"},\"sku\":{\"name\":\"NameForSku\",\"tier\":\"TierForSku\",\"size\":\"SizeForSku\",\"family\":\"FamilyForSku\",\"capacity\":15464547},\"tags\":{},\"type\":\"Microsoft.ClassicStorage/storageAccounts\"}";
JsonElement element = JsonDocument.Parse(json).RootElement;
GenericResourceData data = GenericResourceData.DeserializeGenericResourceData(element);
Assert.IsTrue(data.Id == null);
Assert.IsTrue(data.Kind == null);
}
}
}

0 comments on commit 8724f9d

Please sign in to comment.