From a96274092404d02e20ba67dfe3018cd1b9c9568e Mon Sep 17 00:00:00 2001 From: deleteLater Date: Thu, 16 Mar 2023 17:09:33 +0800 Subject: [PATCH 1/3] get latest data for server & client sdk --- .../src/Api/Public/SdkController.cs | 44 ++++++++++ .../src/Domain/Services/IDataSyncService.cs | 5 ++ .../Services/DataSyncService.cs | 81 ++++++++++--------- 3 files changed, 90 insertions(+), 40 deletions(-) create mode 100644 modules/evaluation-server/src/Api/Public/SdkController.cs diff --git a/modules/evaluation-server/src/Api/Public/SdkController.cs b/modules/evaluation-server/src/Api/Public/SdkController.cs new file mode 100644 index 000000000..c286033b0 --- /dev/null +++ b/modules/evaluation-server/src/Api/Public/SdkController.cs @@ -0,0 +1,44 @@ +using Domain.EndUsers; +using Domain.Services; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Public; + +public class SdkController : PublicApiControllerBase +{ + private readonly IDataSyncService _dataSyncService; + + public SdkController(IDataSyncService dataSyncService) + { + _dataSyncService = dataSyncService; + } + + [HttpGet("server/latest-all")] + public async Task GetServerSideSdkPayloadAsync() + { + if (!Authenticated) + { + return Unauthorized(); + } + + var payload = await _dataSyncService.GetServerSdkPayloadAsync(EnvId, 0); + return new JsonResult(payload); + } + + [HttpPost("client/latest-all")] + public async Task GetClientSdkPayloadAsync([FromQuery] EndUser endUser) + { + if (!Authenticated) + { + return Unauthorized(); + } + + if (!endUser.IsValid()) + { + return BadRequest("invalid end user"); + } + + var payload = await _dataSyncService.GetClientSdkPayloadAsync(EnvId, endUser, 0); + return new JsonResult(payload); + } +} \ No newline at end of file diff --git a/modules/evaluation-server/src/Domain/Services/IDataSyncService.cs b/modules/evaluation-server/src/Domain/Services/IDataSyncService.cs index cc67d54cf..ad0201549 100644 --- a/modules/evaluation-server/src/Domain/Services/IDataSyncService.cs +++ b/modules/evaluation-server/src/Domain/Services/IDataSyncService.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using Domain.EndUsers; using Domain.Protocol; using Domain.WebSockets; @@ -8,6 +9,10 @@ public interface IDataSyncService { Task GetPayloadAsync(Connection connection, DataSyncMessage message); + Task GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp); + + Task GetServerSdkPayloadAsync(Guid envId, long timestamp); + Task GetFlagChangePayloadAsync(Connection connection, JsonElement flag); Task GetSegmentChangePayloadAsync(Connection connection, JsonElement segment, string[] affectedFlagIds); diff --git a/modules/evaluation-server/src/Infrastructure/Services/DataSyncService.cs b/modules/evaluation-server/src/Infrastructure/Services/DataSyncService.cs index 3160ae3d0..e2824ac78 100644 --- a/modules/evaluation-server/src/Infrastructure/Services/DataSyncService.cs +++ b/modules/evaluation-server/src/Infrastructure/Services/DataSyncService.cs @@ -41,6 +41,47 @@ public async Task GetPayloadAsync(Connection connection, DataSyncMessage return payload; } + public async Task GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp) + { + var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch; + var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp); + + var clientSdkFlags = new List(); + foreach (var flagBytes in flagsBytes) + { + using var document = JsonDocument.Parse(flagBytes); + var flag = document.RootElement; + + clientSdkFlags.Add(await GetClientSdkFlagAsync(flag, user)); + } + + return new ClientSdkPayload(eventType, user.KeyId, clientSdkFlags); + } + + public async Task GetServerSdkPayloadAsync(Guid envId, long timestamp) + { + var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch; + var featureFlags = new List(); + var segments = new List(); + + var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp); + foreach (var flag in flagsBytes) + { + var jsonObject = JsonNode.Parse(flag)!.AsObject(); + jsonObject.Remove(""); + featureFlags.Add(jsonObject); + } + + var segmentsBytes = await _cacheService.GetSegmentsAsync(envId, timestamp); + foreach (var segment in segmentsBytes) + { + var jsonObject = JsonNode.Parse(segment)!.AsObject(); + segments.Add(jsonObject); + } + + return new ServerSdkPayload(eventType, featureFlags, segments); + } + public async Task GetFlagChangePayloadAsync(Connection connection, JsonElement flag) { if (connection.Type == ConnectionType.Client && connection.User == null) @@ -118,23 +159,6 @@ private async Task GetClientSdkFlagAsync(JsonElement flag, EndUse return new ClientSdkFlag(flag, userVariation, variations); } - private async Task GetClientSdkPayloadAsync(Guid envId, EndUser user, long timestamp) - { - var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch; - var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp); - - var clientSdkFlags = new List(); - foreach (var flagBytes in flagsBytes) - { - using var document = JsonDocument.Parse(flagBytes); - var flag = document.RootElement; - - clientSdkFlags.Add(await GetClientSdkFlagAsync(flag, user)); - } - - return new ClientSdkPayload(eventType, user.KeyId, clientSdkFlags); - } - #endregion #region get server sdk payload @@ -157,28 +181,5 @@ private ServerSdkPayload GetServerSdkSegmentChangePayload(JsonElement segment) ); } - private async Task GetServerSdkPayloadAsync(Guid envId, long timestamp) - { - var eventType = timestamp == 0 ? DataSyncEventTypes.Full : DataSyncEventTypes.Patch; - var featureFlags = new List(); - var segments = new List(); - - var flagsBytes = await _cacheService.GetFlagsAsync(envId, timestamp); - foreach (var flag in flagsBytes) - { - var jsonObject = JsonNode.Parse(flag)!.AsObject(); - featureFlags.Add(jsonObject); - } - - var segmentsBytes = await _cacheService.GetSegmentsAsync(envId, timestamp); - foreach (var segment in segmentsBytes) - { - var jsonObject = JsonNode.Parse(segment)!.AsObject(); - segments.Add(jsonObject); - } - - return new ServerSdkPayload(eventType, featureFlags, segments); - } - #endregion } \ No newline at end of file From 593e29b5aba07d65e1fdbbebc66c44f7a2cc1c5b Mon Sep 17 00:00:00 2001 From: deleteLater Date: Fri, 17 Mar 2023 13:17:53 +0800 Subject: [PATCH 2/3] fix --- modules/evaluation-server/src/Api/Public/SdkController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/evaluation-server/src/Api/Public/SdkController.cs b/modules/evaluation-server/src/Api/Public/SdkController.cs index c286033b0..3ce0fc58f 100644 --- a/modules/evaluation-server/src/Api/Public/SdkController.cs +++ b/modules/evaluation-server/src/Api/Public/SdkController.cs @@ -25,7 +25,7 @@ public async Task GetServerSideSdkPayloadAsync() return new JsonResult(payload); } - [HttpPost("client/latest-all")] + [HttpGet("client/latest-all")] public async Task GetClientSdkPayloadAsync([FromQuery] EndUser endUser) { if (!Authenticated) From 75f86b8d78e16bc7a56be69de1252547e4af85e1 Mon Sep 17 00:00:00 2001 From: deleteLater Date: Tue, 21 Mar 2023 00:12:49 +0800 Subject: [PATCH 3/3] pr feedback --- .../src/Api/Public/SdkController.cs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/modules/evaluation-server/src/Api/Public/SdkController.cs b/modules/evaluation-server/src/Api/Public/SdkController.cs index 3ce0fc58f..753e1d4ad 100644 --- a/modules/evaluation-server/src/Api/Public/SdkController.cs +++ b/modules/evaluation-server/src/Api/Public/SdkController.cs @@ -22,11 +22,18 @@ public async Task GetServerSideSdkPayloadAsync() } var payload = await _dataSyncService.GetServerSdkPayloadAsync(EnvId, 0); - return new JsonResult(payload); + + var bootstrap = new + { + messageType = "data-sync", + data = payload + }; + + return new JsonResult(bootstrap); } - [HttpGet("client/latest-all")] - public async Task GetClientSdkPayloadAsync([FromQuery] EndUser endUser) + [HttpPost("client/latest-all")] + public async Task GetClientSdkPayloadAsync(EndUser endUser) { if (!Authenticated) { @@ -39,6 +46,14 @@ public async Task GetClientSdkPayloadAsync([FromQuery] EndUser en } var payload = await _dataSyncService.GetClientSdkPayloadAsync(EnvId, endUser, 0); - return new JsonResult(payload); + + var bootstrap = payload.FeatureFlags.Select(x => new + { + x.Id, + x.Variation, + x.VariationType + }); + + return new JsonResult(bootstrap); } } \ No newline at end of file