diff --git a/src/ApiService/ApiService/Functions/AgentEvents.cs b/src/ApiService/ApiService/Functions/AgentEvents.cs index 447bc7d742..bd95191027 100644 --- a/src/ApiService/ApiService/Functions/AgentEvents.cs +++ b/src/ApiService/ApiService/Functions/AgentEvents.cs @@ -16,8 +16,6 @@ public AgentEvents(ILogTracer log, IEndpointAuthorization auth, IOnefuzzContext _context = context; } - private static readonly EntityConverter _entityConverter = new(); - [Function("AgentEvents")] public Async.Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route="agents/events")] @@ -31,7 +29,7 @@ private async Async.Task 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: {_context.EntityConverter.ToJsonString(envelope)}"); var error = envelope.Event switch { NodeStateUpdate updateEvent => await OnStateUpdate(envelope.MachineId, updateEvent), @@ -145,7 +143,7 @@ private async Async.Task 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 = _context.EntityConverter.ToJsonString(doneData); error = new Error(ErrorCode.TASK_FAILED, Errors: new string[] { errorText }); _log.Error($"node 'done' with error: machine_id:{machineId}, data:{errorText}"); } diff --git a/src/ApiService/ApiService/Program.cs b/src/ApiService/ApiService/Program.cs index f7fd2c2df0..7975911a08 100644 --- a/src/ApiService/ApiService/Program.cs +++ b/src/ApiService/ApiService/Program.cs @@ -103,6 +103,7 @@ public async static Async.Task Main() { .AddScoped() .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs b/src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs index 52f357ac9f..013e4b3bda 100644 --- a/src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs +++ b/src/ApiService/ApiService/onefuzzlib/OnefuzzContext.cs @@ -1,4 +1,6 @@ -namespace Microsoft.OneFuzz.Service; +using Microsoft.OneFuzz.Service.OneFuzzLib.Orm; + +namespace Microsoft.OneFuzz.Service; using Microsoft.Extensions.DependencyInjection; @@ -40,6 +42,7 @@ public interface IOnefuzzContext { INsgOperations NsgOperations { get; } ISubnet Subnet { get; } IImageOperations ImageOperations { get; } + EntityConverter EntityConverter { get; } } public class OnefuzzContext : IOnefuzzContext { @@ -85,4 +88,5 @@ public OnefuzzContext(IServiceProvider serviceProvider) { public INsgOperations NsgOperations => _serviceProvider.GetRequiredService(); public ISubnet Subnet => _serviceProvider.GetRequiredService(); public IImageOperations ImageOperations => _serviceProvider.GetRequiredService(); + public EntityConverter EntityConverter => _serviceProvider.GetRequiredService(); } diff --git a/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs b/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs index d610a39eaa..f539ef135b 100644 --- a/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs +++ b/src/ApiService/ApiService/onefuzzlib/WebhookOperations.cs @@ -86,7 +86,6 @@ public async Task Ping(Webhook webhook) { // Not converting to bytes, as it's not neccessary in C#. Just keeping as string. public async Async.Task> 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) }; diff --git a/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs b/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs index 89c5008875..d7b9ef0dfa 100644 --- a/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs +++ b/src/ApiService/ApiService/onefuzzlib/orm/EntityConverter.cs @@ -88,22 +88,24 @@ public override string ConvertName(string name) { } } public class EntityConverter { - private readonly JsonSerializerOptions _options; private readonly ConcurrentDictionary _cache; + private static readonly JsonSerializerOptions _options; + + static EntityConverter() { + _options = new JsonSerializerOptions() { + PropertyNamingPolicy = new OnefuzzNamingPolicy(), + }; + _options.Converters.Add(new CustomEnumConverterFactory()); + _options.Converters.Add(new PolymorphicConverterFactory()); + } public EntityConverter() { - _options = GetJsonSerializerOptions(); _cache = new ConcurrentDictionary(); } 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 BuildConstructerFrom(ConstructorInfo constructorInfo) { diff --git a/src/ApiService/ApiService/onefuzzlib/orm/Orm.cs b/src/ApiService/ApiService/onefuzzlib/orm/Orm.cs index aa62a6ea04..078fdc414c 100644 --- a/src/ApiService/ApiService/onefuzzlib/orm/Orm.cs +++ b/src/ApiService/ApiService/onefuzzlib/orm/Orm.cs @@ -38,7 +38,7 @@ public class Orm : IOrm where T : EntityBase { public Orm(ILogTracer logTracer, IOnefuzzContext context) { _context = context; _logTracer = logTracer; - _entityConverter = new EntityConverter(); + _entityConverter = _context.EntityConverter; } public async IAsyncEnumerable QueryAsync(string? filter = null) { diff --git a/src/ApiService/Tests/RequestsTests.cs b/src/ApiService/Tests/RequestsTests.cs index 3aa80d677c..b79c44e986 100644 --- a/src/ApiService/Tests/RequestsTests.cs +++ b/src/ApiService/Tests/RequestsTests.cs @@ -10,7 +10,7 @@ namespace Tests; // This class contains tests for serialization and -// deserialization of examples generated by the +// deserialization of examples generated by the // onefuzz-agent’s `debug` sub-command. We test each // example for roundtripping which ensures that no // data is lost upon deserialization. @@ -25,7 +25,7 @@ public class RequestsTests { private static JsonSerializerOptions serializationOptions() { // base on the serialization options used at runtime, but // also indent to match inputs: - var result = EntityConverter.GetJsonSerializerOptions(); + var result = new JsonSerializerOptions(EntityConverter.GetJsonSerializerOptions()); result.WriteIndented = true; return result; }