Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Make Entity provider internal static
Browse files Browse the repository at this point in the history
  • Loading branch information
chkeita committed Aug 18, 2022
1 parent e74671b commit bef367f
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 61 deletions.
5 changes: 2 additions & 3 deletions src/ApiService/ApiService/Functions/AgentEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public AgentEvents(ILogTracer log, IEndpointAuthorization auth, IOnefuzzContext
_context = context;
}

private static readonly EntityConverter _entityConverter = new();

[Function("AgentEvents")]
public Async.Task<HttpResponseData> Run(
Expand All @@ -31,7 +30,7 @@ private async Async.Task<HttpResponseData> Post(HttpRequestData req) {
}

var envelope = request.OkV;
_log.Info($"node event: machine_id: {envelope.MachineId} event: {_entityConverter.ToJsonString(envelope)}");
_log.Info($"node event: machine_id: {envelope.MachineId} event: {EntityConverter.ToJsonString(envelope)}");

var error = envelope.Event switch {
NodeStateUpdate updateEvent => await OnStateUpdate(envelope.MachineId, updateEvent),
Expand Down Expand Up @@ -145,7 +144,7 @@ private async Async.Task<HttpResponseData> Post(HttpRequestData req) {
Error? error = null;
if (ev.Data is NodeDoneEventData doneData) {
if (doneData.Error is not null) {
var errorText = _entityConverter.ToJsonString(doneData);
var errorText = EntityConverter.ToJsonString(doneData);
error = new Error(ErrorCode.TASK_FAILED, Errors: new string[] { errorText });
_log.Error($"node 'done' with error: machine_id:{machineId}, data:{errorText}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task<HttpResponseData> Get([HttpTrigger(AuthorizationLevel.Anonymou
await resp.WriteAsJsonAsync(err);
return resp;
} else {
var str = (new EntityConverter()).ToJsonString(config);
var str = EntityConverter.ToJsonString(config);

var resp = req.CreateResponse(HttpStatusCode.OK);
await resp.WriteStringAsync(str);
Expand Down
3 changes: 2 additions & 1 deletion src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using ApiService.OneFuzzLib.Orm;
using Azure.Storage.Sas;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;

namespace Microsoft.OneFuzz.Service;

Expand Down Expand Up @@ -105,7 +106,7 @@ public async Async.Task SaveProxyConfig(Proxy proxy) {
MicrosoftTelemetryKey: _context.ServiceConfiguration.OneFuzzTelemetry.EnsureNotNull("missing Telemetry"),
InstanceId: await _context.Containers.GetInstanceId());

await _context.Containers.SaveBlob(new Container("proxy-configs"), $"{proxy.Region}/{proxy.ProxyId}/config.json", _entityConverter.ToJsonString(proxyConfig), StorageType.Config);
await _context.Containers.SaveBlob(new Container("proxy-configs"), $"{proxy.Region}/{proxy.ProxyId}/config.json", EntityConverter.ToJsonString(proxyConfig), StorageType.Config);
}


Expand Down
1 change: 0 additions & 1 deletion src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public async Task<EventPing> Ping(Webhook webhook) {

// Not converting to bytes, as it's not neccessary in C#. Just keeping as string.
public async Async.Task<Tuple<string, string?>> BuildMessage(Guid webhookId, Guid eventId, EventType eventType, BaseEvent webhookEvent, String? secretToken, WebhookMessageFormat? messageFormat) {
var entityConverter = new EntityConverter();
string data = "";
if (messageFormat != null && messageFormat == WebhookMessageFormat.EventGrid) {
var eventGridMessage = new[] { new WebhookMessageEventGrid(Id: eventId, Data: webhookEvent, DataVersion: "1.0.0", Subject: _context.Creds.GetInstanceName(), EventType: eventType, EventTime: DateTimeOffset.UtcNow) };
Expand Down
31 changes: 15 additions & 16 deletions src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public abstract record EntityBase {
public abstract record StatefulEntityBase<T>([property: JsonIgnore] T BaseState) : EntityBase() where T : Enum;



/// How the value is populated
public enum InitMethod {
//T() will be used
Expand Down Expand Up @@ -88,22 +87,22 @@ public override string ConvertName(string name) {
}
}
public class EntityConverter {
private readonly JsonSerializerOptions _options;
private static readonly JsonSerializerOptions _options;

private readonly ConcurrentDictionary<Type, EntityInfo> _cache;
private static readonly ConcurrentDictionary<Type, EntityInfo> _cache;

public EntityConverter() {
static EntityConverter() {
_options = GetJsonSerializerOptions();
_cache = new ConcurrentDictionary<Type, EntityInfo>();
_options = new JsonSerializerOptions() {
PropertyNamingPolicy = new OnefuzzNamingPolicy(),
};
_options.Converters.Add(new CustomEnumConverterFactory());
_options.Converters.Add(new PolymorphicConverterFactory());
}

public static JsonSerializerOptions GetJsonSerializerOptions() {
var options = new JsonSerializerOptions() {
PropertyNamingPolicy = new OnefuzzNamingPolicy(),
};
options.Converters.Add(new CustomEnumConverterFactory());
options.Converters.Add(new PolymorphicConverterFactory());
return options;
return _options;
}

internal static Func<object?[], object> BuildConstructerFrom(ConstructorInfo constructorInfo) {
Expand Down Expand Up @@ -156,7 +155,7 @@ private static IEnumerable<EntityProperty> GetEntityProperties<T>(ParameterInfo
}


private EntityInfo GetEntityInfo<T>() {
static private EntityInfo GetEntityInfo<T>() {
return _cache.GetOrAdd(typeof(T), type => {
var constructor = type.GetConstructors()[0];
var parameterInfos = constructor.GetParameters();
Expand All @@ -167,11 +166,11 @@ private EntityInfo GetEntityInfo<T>() {
});
}

public string ToJsonString<T>(T typedEntity) => JsonSerializer.Serialize(typedEntity, _options);
static public string ToJsonString<T>(T typedEntity) => JsonSerializer.Serialize(typedEntity, _options);

public T? FromJsonString<T>(string value) => JsonSerializer.Deserialize<T>(value, _options);
static public T? FromJsonString<T>(string value) => JsonSerializer.Deserialize<T>(value, _options);

public TableEntity ToTableEntity<T>(T typedEntity) where T : EntityBase {
static public TableEntity ToTableEntity<T>(T typedEntity) where T : EntityBase {
if (typedEntity == null) {
throw new ArgumentNullException(nameof(typedEntity));
}
Expand Down Expand Up @@ -223,7 +222,7 @@ public TableEntity ToTableEntity<T>(T typedEntity) where T : EntityBase {
}


private object? GetFieldValue(EntityInfo info, string name, TableEntity entity) {
static private object? GetFieldValue(EntityInfo info, string name, TableEntity entity) {
var ef = info.properties[name].First();
if (ef.kind == EntityPropertyKind.PartitionKey || ef.kind == EntityPropertyKind.RowKey) {
if (ef.type == typeof(string))
Expand Down Expand Up @@ -299,7 +298,7 @@ public TableEntity ToTableEntity<T>(T typedEntity) where T : EntityBase {
}


public T ToRecord<T>(TableEntity entity) where T : EntityBase {
static public T ToRecord<T>(TableEntity entity) where T : EntityBase {
var entityInfo = GetEntityInfo<T>();

object?[] parameters;
Expand Down
14 changes: 6 additions & 8 deletions src/ApiService/ApiService/onefuzzlib/orm/Orm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ IAsyncEnumerable<T> SearchByTimeRange((DateTimeOffset min, DateTimeOffset max) r

public class Orm<T> : IOrm<T> where T : EntityBase {
#pragma warning disable CA1051 // permit visible instance fields
protected readonly EntityConverter _entityConverter;
protected readonly IOnefuzzContext _context;
protected readonly ILogTracer _logTracer;
#pragma warning restore CA1051
Expand All @@ -38,7 +37,6 @@ public class Orm<T> : IOrm<T> where T : EntityBase {
public Orm(ILogTracer logTracer, IOnefuzzContext context) {
_context = context;
_logTracer = logTracer;
_entityConverter = new EntityConverter();
}

public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
Expand All @@ -48,7 +46,7 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
filter = null;
}

await foreach (var x in tableClient.QueryAsync<TableEntity>(filter).Select(x => _entityConverter.ToRecord<T>(x))) {
await foreach (var x in tableClient.QueryAsync<TableEntity>(filter).Select(x => EntityConverter.ToRecord<T>(x))) {
yield return x;
}
}
Expand All @@ -57,7 +55,7 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
/// If successful, updates the ETag of the passed-in entity.
public async Task<ResultVoid<(int, string)>> Insert(T entity) {
var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity);
var tableEntity = EntityConverter.ToTableEntity(entity);
var response = await tableClient.AddEntityAsync(tableEntity);

if (response.IsError) {
Expand All @@ -72,7 +70,7 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {

public async Task<ResultVoid<(int, string)>> Replace(T entity) {
var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity);
var tableEntity = EntityConverter.ToTableEntity(entity);
var response = await tableClient.UpsertEntityAsync(tableEntity, TableUpdateMode.Replace);
if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase));
Expand All @@ -87,7 +85,7 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
}

var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity);
var tableEntity = EntityConverter.ToTableEntity(entity);

var response = await tableClient.UpdateEntityAsync(tableEntity, entity.ETag.Value);
if (response.IsError) {
Expand All @@ -100,7 +98,7 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
public async Task<T> GetEntityAsync(string partitionKey, string rowKey) {
var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = await tableClient.GetEntityAsync<TableEntity>(partitionKey, rowKey);
return _entityConverter.ToRecord<T>(tableEntity);
return EntityConverter.ToRecord<T>(tableEntity);
}

public async Task<TableClient> GetTableClient(string table, string? accountId = null) {
Expand All @@ -115,7 +113,7 @@ public async Task<TableClient> GetTableClient(string table, string? accountId =

public async Task<ResultVoid<(int, string)>> Delete(T entity) {
var tableClient = await GetTableClient(typeof(T).Name);
var tableEntity = _entityConverter.ToTableEntity(entity);
var tableEntity = EntityConverter.ToTableEntity(entity);
var response = await tableClient.DeleteEntityAsync(tableEntity.PartitionKey, tableEntity.RowKey);
if (response.IsError) {
return ResultVoid<(int, string)>.Error((response.Status, response.ReasonPhrase));
Expand Down
4 changes: 2 additions & 2 deletions src/ApiService/IntegrationTests/_FunctionTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace IntegrationTests;

// FunctionTestBase contains shared implementations for running
// functions against live Azure Storage or the Azurite emulator.
//
//
// To use this base class, derive an abstract class from this
// with all the tests defined in it. Then, from that class
// derive two non-abstract classes for XUnit to find:
Expand Down Expand Up @@ -59,7 +59,7 @@ protected static string BodyAsString(HttpResponseData data) {
}

protected static T BodyAs<T>(HttpResponseData data)
=> new EntityConverter().FromJsonString<T>(BodyAsString(data)) ?? throw new Exception($"unable to deserialize body as {typeof(T)}");
=> EntityConverter.FromJsonString<T>(BodyAsString(data)) ?? throw new Exception($"unable to deserialize body as {typeof(T)}");

public void Dispose() {
GC.SuppressFinalize(this);
Expand Down
7 changes: 3 additions & 4 deletions src/ApiService/Tests/OrmModelsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -592,17 +592,16 @@ public static bool AreEqual<T>(T r1, T r2) {
}

public class OrmModelsTest {
EntityConverter _converter = new EntityConverter();
ITestOutputHelper _output;

public OrmModelsTest(ITestOutputHelper output) {
Arb.Register<OrmArb>();
_output = output;
}

bool Test<T>(T e) where T : EntityBase {
var v = _converter.ToTableEntity(e);
var r = _converter.ToRecord<T>(v);
static bool Test<T>(T e) where T : EntityBase {
var v = EntityConverter.ToTableEntity(e);
var r = EntityConverter.ToRecord<T>(v);
return EqualityComparison.AreEqual(e, r);

}
Expand Down
37 changes: 14 additions & 23 deletions src/ApiService/Tests/OrmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ record Entity1(
[Fact]
public void TestBothDirections() {
var uriString = new Uri("https://localhost:9090");
var converter = new EntityConverter();
var entity1 = new Entity1(
Guid.NewGuid(),
"test",
Expand All @@ -76,8 +75,8 @@ public void TestBothDirections() {
);


var tableEntity = converter.ToTableEntity(entity1);
var fromTableEntity = converter.ToRecord<Entity1>(tableEntity);
var tableEntity = EntityConverter.ToTableEntity(entity1);
var fromTableEntity = EntityConverter.ToRecord<Entity1>(tableEntity);
var eq = fromTableEntity == entity1;

Assert.Equal(fromTableEntity.TimeStamp, entity1.TimeStamp);
Expand Down Expand Up @@ -105,7 +104,6 @@ public void TestBothDirections() {
[Fact]
public void TestConvertToTableEntity() {
var uriString = new Uri("https://localhost:9090");
var converter = new EntityConverter();
var entity1 = new Entity1(
Guid.NewGuid(),
"test",
Expand All @@ -124,7 +122,7 @@ public void TestConvertToTableEntity() {
uriString,
null
);
var tableEntity = converter.ToTableEntity(entity1);
var tableEntity = EntityConverter.ToTableEntity(entity1);

Assert.NotNull(tableEntity);
Assert.Equal(entity1.Id.ToString(), tableEntity.PartitionKey);
Expand Down Expand Up @@ -154,7 +152,6 @@ public void TestConvertToTableEntity() {

[Fact]
public void TestFromtableEntity() {
var converter = new EntityConverter();
var tableEntity = new TableEntity(Guid.NewGuid().ToString(), "test") {
{"the_date", DateTimeOffset.UtcNow },
{ "the_number", 1234},
Expand All @@ -166,7 +163,7 @@ public void TestFromtableEntity() {
{ "test_null", null},
};

var entity1 = converter.ToRecord<Entity1>(tableEntity);
var entity1 = EntityConverter.ToRecord<Entity1>(tableEntity);

Assert.NotNull(entity1);
Assert.Equal(tableEntity.PartitionKey, entity1.Id.ToString());
Expand Down Expand Up @@ -249,9 +246,8 @@ [RowKey] string TheName
[Fact]
public void TestIntKey() {
var expected = new Entity2(10, "test");
var converter = new EntityConverter();
var tableEntity = converter.ToTableEntity(expected);
var actual = converter.ToRecord<Entity2>(tableEntity);
var tableEntity = EntityConverter.ToTableEntity(expected);
var actual = EntityConverter.ToRecord<Entity2>(tableEntity);

Assert.Equal(expected.Id, actual.Id);
Assert.Equal(expected.TheName, actual.TheName);
Expand All @@ -267,10 +263,9 @@ Container Container
public void TestContainerSerialization() {
var container = new Container("abc-123");
var expected = new Entity3(123, "abc", container);
var converter = new EntityConverter();

var tableEntity = converter.ToTableEntity(expected);
var actual = converter.ToRecord<Entity3>(tableEntity);
var tableEntity = EntityConverter.ToTableEntity(expected);
var actual = EntityConverter.ToRecord<Entity3>(tableEntity);

Assert.Equal(expected.Container.ContainerName, actual.Container.ContainerName);
Assert.Equal(expected.Container.ContainerName, tableEntity.GetString("container"));
Expand Down Expand Up @@ -302,13 +297,12 @@ Container Container
public void TestPartitionKeyIsRowKey() {
var container = new Container("abc-123");
var expected = new Entity4(123, "abc", container);
var converter = new EntityConverter();

var tableEntity = converter.ToTableEntity(expected);
var tableEntity = EntityConverter.ToTableEntity(expected);
Assert.Equal(expected.Id.ToString(), tableEntity.RowKey);
Assert.Equal(expected.Id.ToString(), tableEntity.PartitionKey);

var actual = converter.ToRecord<Entity4>(tableEntity);
var actual = EntityConverter.ToRecord<Entity4>(tableEntity);

Assert.Equal(expected.Container.ContainerName, actual.Container.ContainerName);
Assert.Equal(expected.Container.ContainerName, tableEntity.GetString("container"));
Expand Down Expand Up @@ -336,8 +330,7 @@ record TestNullField(int? Id, string? Name, TestObject? Obj) : EntityBase();
[Fact]
public void TestNullValue() {

var entityConverter = new EntityConverter();
var tableEntity = entityConverter.ToTableEntity(new TestNullField(null, null, null));
var tableEntity = EntityConverter.ToTableEntity(new TestNullField(null, null, null));

Assert.Null(tableEntity["id"]);
Assert.Null(tableEntity["name"]);
Expand Down Expand Up @@ -367,14 +360,13 @@ record TestEntity3(DoNotRename Enum, DoNotRenameFlag flag) : EntityBase();
[Fact]
public void TestSkipRename() {

var entityConverter = new EntityConverter();

var expected = new TestEntity3(DoNotRename.TEST3, DoNotRenameFlag.Test_2 | DoNotRenameFlag.test1);
var tableEntity = entityConverter.ToTableEntity(expected);
var tableEntity = EntityConverter.ToTableEntity(expected);
Assert.Equal("TEST3", tableEntity.GetString("enum"));
Assert.Equal("test1,Test_2", tableEntity.GetString("flag"));

var actual = entityConverter.ToRecord<TestEntity3>(tableEntity);
var actual = EntityConverter.ToRecord<TestEntity3>(tableEntity);

Assert.Equal(expected, actual);
}
Expand All @@ -390,9 +382,8 @@ record TestIinit([DefaultValue(InitMethod.DefaultConstructor)] TestClass testCla

[Fact]
public void TestInitValue() {
var entityConverter = new EntityConverter();
var tableEntity = new TableEntity();
var actual = entityConverter.ToRecord<TestIinit>(tableEntity);
var actual = EntityConverter.ToRecord<TestIinit>(tableEntity);

Assert.Equal("testName", actual.testClass.Name);
Assert.Equal("default_test", actual.test);
Expand Down
Loading

0 comments on commit bef367f

Please sign in to comment.