Skip to content

Commit

Permalink
[1ES] Migrate Scale Metrics to Azure.Data.Tables (#10276)
Browse files Browse the repository at this point in the history
* Migrating Scale Metrics to Azure.Data.Tables

* Address feedback

* Configuring transport for TableServiceClient when we have a DelegatingHandler

* Cleanup

* Check if exception is fatal

Co-authored-by: Jacob Viau <javia@microsoft.com>

* Using string filters on hot paths to avoid parsing expressions

* Logging exception message instead of dumping full exception

* Create table service clients using an storage provider which also supports token credentials.

* Mock IAzureTableStorageProvider for TestWebScriptHost

* Address feedback

Co-authored-by: Shyju Krishnankutty <connectshyju@gmail.com>

* Address feedback

* Add release notes

* HostAzureTableStorageProvider sealed

* Fix variable name in test helpers

* Addresed feedback.

* Revert DelegatingHandler changes

---------

Co-authored-by: Jacob Viau <javia@microsoft.com>
Co-authored-by: Shyju Krishnankutty <connectshyju@gmail.com>
Co-authored-by: Fabio Cavalcante <facaval@microsoft.com>
  • Loading branch information
4 people authored Aug 27, 2024
1 parent bcdd593 commit 44489a3
Show file tree
Hide file tree
Showing 16 changed files with 548 additions and 327 deletions.
2 changes: 2 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@
- Worker termination path updated with sanitized logging (#10367)
- Avoid redundant DiagnosticEvents error message (#10395)
- Added logic to shim older versions of the .NET Worker JsonFunctionProvider to ensure backwards compatibility (#10410)
- Migrated Scale Metrics to use `Azure.Data.Tables` SDK (#10276)
- Added support for Identity-based connections
78 changes: 20 additions & 58 deletions src/WebJobs.Script.WebHost/Scale/TableEntityConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@

using System;
using System.Collections.Generic;
using Microsoft.Azure.Cosmos.Table;
using Azure;
using Azure.Data.Tables;
using Newtonsoft.Json.Linq;

namespace Microsoft.Azure.WebJobs.Script.WebHost.Scale
{
/// <summary>
/// Class providing methods to convert between DynamicTableEntity and custom pocos
/// Class providing methods to convert between <see cref="TableEntity"/> and custom pocos.
/// </summary>
internal static class TableEntityConverter
{
public static DynamicTableEntity ToEntity(object o,
public static TableEntity ToEntity(object o,
string partitionKey = null,
string rowKey = null,
DateTimeOffset? timeStamp = null,
string etag = null)
{
var entity = new DynamicTableEntity
var entity = new TableEntity
{
RowKey = rowKey,
PartitionKey = partitionKey,
Properties = new Dictionary<string, EntityProperty>()
PartitionKey = partitionKey
};

if (timeStamp.HasValue)
Expand All @@ -33,108 +33,70 @@ public static DynamicTableEntity ToEntity(object o,

if (!string.IsNullOrWhiteSpace(etag))
{
entity.ETag = etag;
entity.ETag = new ETag(etag);
}

var jo = JObject.FromObject(o);
foreach (var prop in jo.Properties())
{
if (TryGetEntityProperty(prop, out EntityProperty entityProperty))
if (TryGetEntityProperty(prop, out object value))
{
entity.Properties.Add(prop.Name, entityProperty);
entity.Add(prop.Name, value);
}
}

return entity;
}

public static object ToObject(Type type, DynamicTableEntity entity)
{
return ToObject(type, entity.Properties);
}

public static TOutput ToObject<TOutput>(IDictionary<string, EntityProperty> properties)
public static TOutput ToObject<TOutput>(IDictionary<string, object> properties)
{
return (TOutput)ToObject(typeof(TOutput), properties);
}

public static object ToObject(Type type, IDictionary<string, EntityProperty> properties)
public static object ToObject(Type type, IDictionary<string, object> properties)
{
var jo = new JObject();
foreach (var pair in properties)
{
ApplyProperty(jo, pair.Key, pair.Value);
jo.Add(pair.Key, new JValue(pair.Value));
}
return jo.ToObject(type);
}

public static bool TryGetEntityProperty(JProperty property, out EntityProperty entityProperty)
public static bool TryGetEntityProperty(JProperty property, out object entityProperty)
{
entityProperty = null;
var value = property.Value;

switch (value.Type)
{
case JTokenType.Bytes:
entityProperty = new EntityProperty(value.ToObject<byte[]>());
entityProperty = value.ToObject<byte[]>();
return true;
case JTokenType.Boolean:
entityProperty = new EntityProperty(value.ToObject<bool>());
entityProperty = value.ToObject<bool>();
return true;
case JTokenType.Date:
entityProperty = new EntityProperty(value.ToObject<DateTime>());
entityProperty = value.ToObject<DateTime>();
return true;
case JTokenType.Float:
entityProperty = new EntityProperty(value.ToObject<double>());
entityProperty = value.ToObject<double>();
return true;
case JTokenType.Guid:
entityProperty = new EntityProperty(value.ToObject<Guid>());
entityProperty = value.ToObject<Guid>();
return true;
case JTokenType.Integer:
// to handle both ints and longs, we normalize integer values
// to type long
entityProperty = new EntityProperty(value.ToObject<long>());
entityProperty = value.ToObject<long>();
return true;
case JTokenType.String:
case JTokenType.TimeSpan:
entityProperty = new EntityProperty(value.ToObject<string>());
entityProperty = value.ToObject<string>();
return true;
default:
return false;
}
}

public static void ApplyProperty(JObject jo, string name, EntityProperty entityProperty)
{
switch (entityProperty.PropertyType)
{
case EdmType.Binary:
jo.Add(name, new JValue(entityProperty.BinaryValue));
return;
case EdmType.Boolean:
jo.Add(name, new JValue(entityProperty.BooleanValue));
return;
case EdmType.DateTime:
jo.Add(name, new JValue(entityProperty.DateTime));
return;
case EdmType.Double:
jo.Add(name, new JValue(entityProperty.DoubleValue));
return;
case EdmType.Guid:
jo.Add(name, new JValue(entityProperty.GuidValue));
return;
case EdmType.Int32:
jo.Add(name, new JValue(entityProperty.Int32Value));
return;
case EdmType.Int64:
jo.Add(name, new JValue(entityProperty.Int64Value));
return;
case EdmType.String:
jo.Add(name, new JValue(entityProperty.StringValue));
return;
default:
return;
}
}
}
}
Loading

0 comments on commit 44489a3

Please sign in to comment.