Skip to content

Commit

Permalink
ref(subscribe): refactored subscribe events data parsing/deserializat…
Browse files Browse the repository at this point in the history
…ion implementation
  • Loading branch information
Mohit Tejani authored and Mohit Tejani committed Jan 13, 2025
1 parent 59ba055 commit 5426639
Show file tree
Hide file tree
Showing 11 changed files with 612 additions and 280 deletions.
12 changes: 10 additions & 2 deletions src/Api/PubnubApi/Builder/ResponseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ internal class ResponseBuilder
private readonly PNConfiguration config;
private readonly IJsonPluggableLibrary jsonLib;
private readonly IPubnubLog pubnubLog;
private readonly NewtonsoftJsonDotNet newtonsoftJsonDotNet;
private readonly EventDeserializer eventDeserializer;

public ResponseBuilder(PNConfiguration pubnubConfig, IJsonPluggableLibrary jsonPluggableLibrary, IPubnubLog log)
{
config = pubnubConfig;
jsonLib = jsonPluggableLibrary;
pubnubLog = log;
newtonsoftJsonDotNet = new NewtonsoftJsonDotNet(config, pubnubLog);
eventDeserializer = new EventDeserializer(jsonLib, newtonsoftJsonDotNet);
}

public T JsonToObject<T>(List<object> result, bool internalObject)
Expand All @@ -25,11 +29,15 @@ public T JsonToObject<T>(List<object> result, bool internalObject)
}
else
{
NewtonsoftJsonDotNet jsonNewtonLib = new NewtonsoftJsonDotNet(config, pubnubLog);
ret = jsonNewtonLib.DeserializeToObject<T>(result);
ret = newtonsoftJsonDotNet.DeserializeToObject<T>(result);
}

return ret;
}

public T GetEventResultObject<T>(IDictionary<string, object> jsonFields)
{
return eventDeserializer.Deserialize<T>(jsonFields);
}
}
}
480 changes: 303 additions & 177 deletions src/Api/PubnubApi/EventEngine/Common/EventEmitter.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -905,24 +905,6 @@ public static T DeserializeToInternalObject<T>(IJsonPluggableLibrary jsonPlug, L

#endregion
}
else if (typeof(T) == typeof(PNObjectEventResult))
{
#region "PNObjectEventResult"

PNObjectEventResult result = PNObjectEventJsonDataParse.GetObject(jsonPlug, listObject);
ret = (T)Convert.ChangeType(result, typeof(PNObjectEventResult), CultureInfo.InvariantCulture);

#endregion
}
else if (typeof(T) == typeof(PNMessageActionEventResult))
{
#region "PNMessageActionEventResult"

PNMessageActionEventResult result = PNMessageActionEventJsonDataParse.GetObject(jsonPlug, listObject);
ret = (T)Convert.ChangeType(result, typeof(PNMessageActionEventResult), CultureInfo.InvariantCulture);

#endregion
}
else if (typeof(T) == typeof(PNAddMessageActionResult))
{
#region "PNAddMessageActionResult"
Expand Down
146 changes: 146 additions & 0 deletions src/Api/PubnubApi/JsonDataParse/EventDeserializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;

namespace PubnubApi;

public class EventDeserializer
{
private readonly IJsonPluggableLibrary jsonLibrary;
private readonly NewtonsoftJsonDotNet newtonSoftJsonLibrary; // the default serializer of sdk

public EventDeserializer(IJsonPluggableLibrary jsonLibrary, NewtonsoftJsonDotNet newtonSoftJsonLibrary)
{
this.jsonLibrary = jsonLibrary;
this.newtonSoftJsonLibrary = newtonSoftJsonLibrary;
}

public T Deserialize<T>(IDictionary<string, object> json)
{
T response = default(T);
var typeInfo = typeof(T);
if (typeInfo.GetTypeInfo().IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(PNMessageResult<>))
{
response = newtonSoftJsonLibrary.DeserializeMessageResultEvent<T>(json);
}
else if (typeof(T) == typeof(PNObjectEventResult))
{
PNObjectEventResult objectEvent = PNObjectEventJsonDataParse.GetObject(jsonLibrary, json);
response = (T)Convert.ChangeType(objectEvent, typeof(PNObjectEventResult), CultureInfo.InvariantCulture);
}
else if (typeof(T) == typeof(PNPresenceEventResult))
{
PNPresenceEventResult presenceEvent = DeserializePresenceEvent(json);
response = (T)Convert.ChangeType(presenceEvent, typeof(PNPresenceEventResult), CultureInfo.InvariantCulture);
}

else if (typeof(T) == typeof(PNMessageActionEventResult))
{
PNMessageActionEventResult messageActionEvent = PNMessageActionEventJsonDataParse.GetObject(jsonLibrary, json);
response = (T)Convert.ChangeType(messageActionEvent, typeof(PNMessageActionEventResult), CultureInfo.InvariantCulture);
}

return response;
}

private PNPresenceEventResult DeserializePresenceEvent(IDictionary<string, object> jsonFields)
{
Dictionary<string, object> presenceDicObj = jsonLibrary.ConvertToDictionaryObject(jsonFields["payload"]);

PNPresenceEventResult presenceEvent = null;

if (presenceDicObj != null)
{
presenceEvent = new PNPresenceEventResult();
presenceEvent.Event = presenceDicObj["action"].ToString();
long presenceTimeStamp;
if (Int64.TryParse(presenceDicObj["timestamp"].ToString(), out presenceTimeStamp))
{
presenceEvent.Timestamp = presenceTimeStamp;
}

if (presenceDicObj.TryGetValue("uuid", out var value))
{
presenceEvent.Uuid = value.ToString();
}

if (Int32.TryParse(presenceDicObj["occupancy"].ToString(), out var presenceOccupany))
{
presenceEvent.Occupancy = presenceOccupany;
}

if (presenceDicObj.TryGetValue("data", out var presenceEventDataField))
{
if (presenceEventDataField is Dictionary<string, object> presenceData)
{
presenceEvent.State = presenceData;
}
}

if (Int64.TryParse(jsonFields["publishTimetoken"].ToString(), out var presenceTimetoken))
{
presenceEvent.Timetoken = presenceTimetoken;
}

presenceEvent.Channel = jsonFields["channel"]?.ToString();
presenceEvent.Channel = presenceEvent.Channel?.Replace("-pnpres", "");


presenceEvent.Subscription = jsonFields["channelGroup"]?.ToString();
presenceEvent.Subscription = presenceEvent.Subscription?.Replace("-pnpres", "");


if (jsonFields["userMetadata"] != null)
{
presenceEvent.UserMetadata = jsonFields["userMetadata"];
}

if (presenceEvent.Event != null && presenceEvent.Event.ToLowerInvariant() == "interval")
{
if (presenceDicObj.TryGetValue("join", out var joinUserList))
{
List<object> joinDeltaList = joinUserList as List<object>;
if (joinDeltaList is { Count: > 0 })
{
presenceEvent.Join = joinDeltaList.Select(x => x.ToString()).ToArray();
}
}

if (presenceDicObj.ContainsKey("timeout"))
{
List<object> timeoutDeltaList = presenceDicObj["timeout"] as List<object>;
if (timeoutDeltaList != null && timeoutDeltaList.Count > 0)
{
presenceEvent.Timeout = timeoutDeltaList.Select(x => x.ToString()).ToArray();
}
}

if (presenceDicObj.ContainsKey("leave"))
{
List<object> leaveDeltaList = presenceDicObj["leave"] as List<object>;
if (leaveDeltaList != null && leaveDeltaList.Count > 0)
{
presenceEvent.Leave = leaveDeltaList.Select(x => x.ToString()).ToArray();
}
}

if (presenceDicObj.ContainsKey("here_now_refresh"))
{
string hereNowRefreshStr = presenceDicObj["here_now_refresh"].ToString();
if (!string.IsNullOrEmpty(hereNowRefreshStr))
{
bool boolHereNowRefresh = false;
if (Boolean.TryParse(hereNowRefreshStr, out boolHereNowRefresh))
{
presenceEvent.HereNowRefresh = boolHereNowRefresh;
}
}
}
}
}

return presenceEvent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace PubnubApi
{
internal static class PNMessageActionEventJsonDataParse
{
internal static PNMessageActionEventResult GetObject(IJsonPluggableLibrary jsonPlug, List<object> listObject)
internal static PNMessageActionEventResult GetObject(IJsonPluggableLibrary jsonPlug, IDictionary<string, object> listObject)
{
PNMessageActionEventResult result = null;

Dictionary<string, object> msgActionEventDicObj = jsonPlug.ConvertToDictionaryObject(listObject[0]);
Dictionary<string, object> msgActionEventDicObj = jsonPlug.ConvertToDictionaryObject(listObject["payload"]);
if (msgActionEventDicObj != null)
{
result = new PNMessageActionEventResult();
Expand Down Expand Up @@ -43,12 +43,10 @@ internal static PNMessageActionEventResult GetObject(IJsonPluggableLibrary jsonP
};
}
}
result.Uuid = listObject[3].ToString();
result.Subscription = listObject[4]?.ToString();
result.Channel = listObject[5]?.ToString();

result.Uuid = listObject["userId"]?.ToString();
result.Subscription = listObject["channelGroup"]?.ToString();
result.Channel = listObject["channel"]?.ToString();
}

return result;
}
}
Expand Down
68 changes: 31 additions & 37 deletions src/Api/PubnubApi/JsonDataParse/PNObjectEventJsonDataParse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,25 @@ namespace PubnubApi
{
internal static class PNObjectEventJsonDataParse
{
internal static PNObjectEventResult GetObject(IJsonPluggableLibrary jsonPlug, List<object> listObject)
internal static PNObjectEventResult GetObject(IJsonPluggableLibrary jsonPlug, IDictionary<string, object> jsonFields)
{
PNObjectEventResult result = null;

Dictionary<string, object> objectEventDicObj = (listObject != null && listObject.Count > 0) ? jsonPlug.ConvertToDictionaryObject(listObject[0]) : null;
Dictionary<string, object> objectEventDicObj = jsonFields is { Count: > 0 } ? jsonPlug.ConvertToDictionaryObject(jsonFields["payload"]) : null;
if (objectEventDicObj != null)
{
if (result == null)
{
result = new PNObjectEventResult();
}
result = new PNObjectEventResult();

if (objectEventDicObj.ContainsKey("event") && objectEventDicObj["event"] != null)
{
result.Event = objectEventDicObj["event"].ToString();
}

if (listObject.Count > 2)
if (Int64.TryParse(jsonFields["publishTimetoken"]?.ToString(), out var objectEventTimeStamp))
{
long objectEventTimeStamp;
if (Int64.TryParse(listObject[2].ToString(), out objectEventTimeStamp))
{
result.Timestamp = objectEventTimeStamp;
}
result.Timestamp = objectEventTimeStamp;
}


if (objectEventDicObj.ContainsKey("type") && objectEventDicObj["type"] != null)
{
Expand All @@ -38,58 +32,58 @@ internal static PNObjectEventResult GetObject(IJsonPluggableLibrary jsonPlug, Li

if (objectEventDicObj.ContainsKey("data") && objectEventDicObj["data"] != null)
{
Dictionary<string, object> dataDic = objectEventDicObj["data"] as Dictionary<string, object>;
if (dataDic != null)
Dictionary<string, object> dataFields = objectEventDicObj["data"] as Dictionary<string, object>;
if (dataFields != null)
{
if (result.Type.ToLowerInvariant() == "uuid" && dataDic.ContainsKey("id"))
if (result.Type?.ToLowerInvariant() == "uuid" && dataFields.ContainsKey("id"))
{
result.UuidMetadata = new PNUuidMetadataResult
{
Uuid = dataDic["id"] != null ? dataDic["id"].ToString() : null,
Name = (dataDic.ContainsKey("name") && dataDic["name"] != null) ? dataDic["name"].ToString() : null,
ExternalId = (dataDic.ContainsKey("externalId") && dataDic["externalId"] != null) ? dataDic["externalId"].ToString() : null,
ProfileUrl = (dataDic.ContainsKey("profileUrl") && dataDic["profileUrl"] != null) ? dataDic["profileUrl"].ToString() : null,
Email = (dataDic.ContainsKey("email") && dataDic["email"] != null) ? dataDic["email"].ToString() : null,
Custom = (dataDic.ContainsKey("custom") && dataDic["custom"] != null) ? jsonPlug.ConvertToDictionaryObject(dataDic["custom"]) : null,
Updated = (dataDic.ContainsKey("updated") && dataDic["updated"] != null) ? dataDic["updated"].ToString() : null
Uuid = dataFields["id"]?.ToString(),
Name = (dataFields.ContainsKey("name") && dataFields["name"] != null) ? dataFields["name"].ToString() : null,
ExternalId = (dataFields.ContainsKey("externalId") && dataFields["externalId"] != null) ? dataFields["externalId"].ToString() : null,
ProfileUrl = (dataFields.ContainsKey("profileUrl") && dataFields["profileUrl"] != null) ? dataFields["profileUrl"].ToString() : null,
Email = (dataFields.ContainsKey("email") && dataFields["email"] != null) ? dataFields["email"].ToString() : null,
Custom = (dataFields.ContainsKey("custom") && dataFields["custom"] != null) ? jsonPlug.ConvertToDictionaryObject(dataFields["custom"]) : null,
Updated = (dataFields.ContainsKey("updated") && dataFields["updated"] != null) ? dataFields["updated"].ToString() : null
};
}
else if (result.Type.ToLowerInvariant() == "channel" && dataDic.ContainsKey("id"))
else if (result.Type.ToLowerInvariant() == "channel" && dataFields.ContainsKey("id"))
{
result.ChannelMetadata = new PNChannelMetadataResult
{
Channel = dataDic["id"] != null ? dataDic["id"].ToString() : null,
Name = (dataDic.ContainsKey("name") && dataDic["name"] != null) ? dataDic["name"].ToString() : null,
Description = (dataDic.ContainsKey("description") && dataDic["description"] != null) ? dataDic["description"].ToString() : null,
Custom = (dataDic.ContainsKey("custom") && dataDic["custom"] != null) ? jsonPlug.ConvertToDictionaryObject(dataDic["custom"]) : null,
Updated = (dataDic.ContainsKey("updated") && dataDic["updated"] != null) ? dataDic["updated"].ToString() : null
Channel = dataFields["id"]?.ToString(),
Name = (dataFields.ContainsKey("name") && dataFields["name"] != null) ? dataFields["name"].ToString() : null,
Description = (dataFields.ContainsKey("description") && dataFields["description"] != null) ? dataFields["description"].ToString() : null,
Custom = (dataFields.ContainsKey("custom") && dataFields["custom"] != null) ? jsonPlug.ConvertToDictionaryObject(dataFields["custom"]) : null,
Updated = (dataFields.ContainsKey("updated") && dataFields["updated"] != null) ? dataFields["updated"].ToString() : null
};
}
else if (result.Type.ToLowerInvariant() == "membership" && dataDic.ContainsKey("uuid") && dataDic.ContainsKey("channel"))
else if (result.Type.ToLowerInvariant() == "membership" && dataFields.ContainsKey("uuid") && dataFields.ContainsKey("channel"))
{
Dictionary<string, object> uuidMetadataIdDic = dataDic["uuid"] as Dictionary<string, object>;
if (uuidMetadataIdDic != null && uuidMetadataIdDic.ContainsKey("id"))
Dictionary<string, object> userMetadataFields = dataFields["uuid"] as Dictionary<string, object>;
if (userMetadataFields != null && userMetadataFields.ContainsKey("id"))
{
result.UuidMetadata = new PNUuidMetadataResult
{
Uuid = uuidMetadataIdDic["id"] != null ? uuidMetadataIdDic["id"].ToString() : null
Uuid = userMetadataFields["id"]?.ToString()
};
}

Dictionary<string, object> channelMetadataIdDic = dataDic["channel"] as Dictionary<string, object>;
if (channelMetadataIdDic != null && channelMetadataIdDic.ContainsKey("id"))
Dictionary<string, object> channelMetadataFields = dataFields["channel"] as Dictionary<string, object>;
if (channelMetadataFields != null && channelMetadataFields.ContainsKey("id"))
{
result.ChannelMetadata = new PNChannelMetadataResult
{
Channel = channelMetadataIdDic["id"] != null ? channelMetadataIdDic["id"].ToString() : null
Channel = channelMetadataFields["id"]?.ToString()
};
}

}
}
}
result.Subscription = listObject[4]?.ToString();
result.Channel = listObject[5].ToString();
result.Subscription = jsonFields["channelGroup"]?.ToString();
result.Channel = jsonFields["channel"].ToString();
}

return result;
Expand Down
Loading

0 comments on commit 5426639

Please sign in to comment.