Skip to content

Commit

Permalink
feat: customMessageType and MembershipType (#230)
Browse files Browse the repository at this point in the history
* CustomMessageType Support for publish, subscribe, Signal, Files.
Acceptance Tests step implementation for custom messageType

* fix: test implementation of customMessageType

* fix: test implementation

* fix(presenceEventDataParsing): fixed issue in presence event data parsing arise due to change in list of serialized object values indexing differences happened after customtype introduction

* feat: support for `status` and `type` for membership,
fix: files api subscribe event data parsing issue

* fix Unit Test implementation for Files api,
Added missing parsing information for message Actions response,
Fix delete files response giving wrong error information even the call is successfull,
Updated change long for last release about breaking change on reconnection policy

* Add a custom object deserialization test

* fix: message serialisation to custom type not being casted to T in emitEvent method

* Test enabling EE for tests + new Presence callback test

* Remove new faulty test

* fix: tests and emitStatus related issue, Dicsonnected category status does not need statusCode as per event engine specification

* taxk-1: fix acceptance Tests failure in eventEngine

* take-1: fix customObject receive Test failure

* fix: test implementation for history call check

* fix signal tests implementation to avoid race condition of getting disconnected error

* fix: update test implementation for subscription, eventEngine will not emit same status of connected again when a new channel entity is added to subscription

* fix(ut): SubscribeToChannel3- EnableEventEngine reset

* fix(ut): subscribe:cleanup for subscribe tests implementation

* fix(eventEmitter): exception handling during usermessage callback, as serialisation can be customisable via user providered pluggable serialisation function

* fix(ut):userMetadata: test data cleanup as getAllMetadata was not fetching the assert test entities

* fix test implementation of with wildcard channel subscription, updated chancel method of EmitMessages effect

* Add a test for custom object subscription presence callbacks

* Update EmitMessagesHandler.cs to fix serialization issue for non custom type payload objects

* fix(unitTest): apply randomness in userId, so that subscribe call can trigger `join` event when a subscequent subscription call to same channel by same user is happening due to sequential subscribe test execution within few seconds to prod server

* fix(unit test- presence event): added random unique channel name so that join event will be emitted when a new subscription is created and do not conflict with old execution"s join event within very short time duration

* PubNub SDK v7.1.0.0 release.

---------

Co-authored-by: PUBNUB\jakub.grzesiowski <[email protected]>
Co-authored-by: PubNub Release Bot <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2024
1 parent 7f4180c commit 59ba055
Show file tree
Hide file tree
Showing 72 changed files with 2,969 additions and 584 deletions.
23 changes: 15 additions & 8 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
name: c-sharp
version: "7.0.0"
version: "7.1.0"
schema: 1
scm: github.com/pubnub/c-sharp
changelog:
- date: 2024-12-04
version: v7.1.0
changes:
- type: feature
text: "Added support for CustomMessageType in publish, signal, files features."
- type: feature
text: "Added support for Type field in membership APIs."
- date: 2024-10-30
version: v7.0.0
changes:
- type: feature
text: "Added support for `Channel`, `ChannelGroup`, `Subscription` and `SubscriptionSet`, `ChannelMetadata`, `UserMetadata` entities for Subscribe related operation."
- type: feature
text: "BREAKING CHANGES: Added new event listeners support."
text: "BREAKING CHANGES: Default Reconnection policy is set to Exponential."
- type: feature
text: "BREAKING CHANGES: All apis calls will be made through `HttpClient` by default."
- type: feature
Expand Down Expand Up @@ -806,7 +813,7 @@ features:
- QUERY-PARAM
supported-platforms:
-
version: Pubnub 'C#' 7.0.0
version: Pubnub 'C#' 7.1.0
platforms:
- Windows 10 and up
- Windows Server 2008 and up
Expand All @@ -817,7 +824,7 @@ supported-platforms:
- .Net Framework 4.6.1+
- .Net Framework 6.0
-
version: PubnubPCL 'C#' 7.0.0
version: PubnubPCL 'C#' 7.1.0
platforms:
- Xamarin.Android
- Xamarin.iOS
Expand All @@ -837,7 +844,7 @@ supported-platforms:
- .Net Core
- .Net 6.0
-
version: PubnubUWP 'C#' 7.0.0
version: PubnubUWP 'C#' 7.1.0
platforms:
- Windows Phone 10
- Universal Windows Apps
Expand All @@ -861,7 +868,7 @@ sdks:
distribution-type: source
distribution-repository: GitHub
package-name: Pubnub
location: https://github.com/pubnub/c-sharp/releases/tag/v7.0.0.0
location: https://github.com/pubnub/c-sharp/releases/tag/v7.1.0.0
requires:
-
name: ".Net"
Expand Down Expand Up @@ -1144,7 +1151,7 @@ sdks:
distribution-type: source
distribution-repository: GitHub
package-name: PubNubPCL
location: https://github.com/pubnub/c-sharp/releases/tag/v7.0.0.0
location: https://github.com/pubnub/c-sharp/releases/tag/v7.1.0.0
requires:
-
name: ".Net Core"
Expand Down Expand Up @@ -1503,7 +1510,7 @@ sdks:
distribution-type: source
distribution-repository: GitHub
package-name: PubnubUWP
location: https://github.com/pubnub/c-sharp/releases/tag/v7.0.0.0
location: https://github.com/pubnub/c-sharp/releases/tag/v7.1.0.0
requires:
-
name: "Universal Windows Platform Development"
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v7.1.0 - December 04 2024
-----------------------------
- Added: added support for CustomMessageType in publish, signal, files features.
- Added: added support for Type field in membership APIs.

v7.0.0 - October 30 2024
-----------------------------
- Added: added support for `Channel`, `ChannelGroup`, `Subscription` and `SubscriptionSet`, `ChannelMetadata`, `UserMetadata` entities for Subscribe related operation.
Expand Down
2 changes: 1 addition & 1 deletion src/Api/PubnubApi/Builder/StatusBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public PNStatus CreateStatusResponse<T>(PNOperationType type, PNStatusCategory c
status.Category = PNStatusCategory.PNAccessDeniedCategory;
}


status.Uuid = config.UserId;
status.Origin = config.Origin;
status.TlsEnabled = config.Secure;

Expand Down
8 changes: 8 additions & 0 deletions src/Api/PubnubApi/Builder/UrlParameterConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ public static string MapEnumValueToEndpoint(string enumValue)
{
endpointParameterName = "uuid.custom";
}
else if (enumValue.ToLowerInvariant() == "status")
{
endpointParameterName = "status";
}
else if (enumValue.ToLowerInvariant() == "type")
{
endpointParameterName = "type";
}

return endpointParameterName;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Api/PubnubApi/EndPoint/Files/DeleteFileOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ private void ProcessDeleteFileRequest(Dictionary<string, object> externalQueryPa
PubnubInstance.transportMiddleware.Send(transportRequest: transportRequest).ContinueWith(t => {
var transportResponse = t.Result;
if (transportResponse.Error == null) {
requestState.GotJsonResponse = true;
var responseString = Encoding.UTF8.GetString(transportResponse.Content);
if (!string.IsNullOrEmpty(responseString)) {
List<object> result = ProcessJsonResponse(requestState, responseString);
Expand Down Expand Up @@ -140,6 +141,7 @@ private async Task<PNResult<PNDeleteFileResult>> ProcessDeleteFileRequest(Dictio
var transportRequest = PubnubInstance.transportMiddleware.PreapareTransportRequest(requestParameter: requestParameter, operationType: PNOperationType.PNDeleteFileOperation);
var transportResponse = await PubnubInstance.transportMiddleware.Send(transportRequest: transportRequest).ConfigureAwait(false);
if (transportResponse.Error == null) {
requestState.GotJsonResponse = true;
var responseString = Encoding.UTF8.GetString(transportResponse.Content);
PNStatus errorStatus = GetStatusIfError(requestState, responseString);
if (errorStatus == null) {
Expand Down
10 changes: 10 additions & 0 deletions src/Api/PubnubApi/EndPoint/Files/PublishFileMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class PublishFileMessageOperation : PubnubCoreBase
private object publishMessageContent;
private bool storeInHistory = true;
private Dictionary<string, object> userMetadata;
private string customMessageType;
private int ttl = -1;

public PublishFileMessageOperation(PNConfiguration pubnubConfig, IJsonPluggableLibrary jsonPluggableLibrary, IPubnubUnitTest pubnubUnit, IPubnubLog log, EndPoint.TokenManager tokenManager, Pubnub instance) : base(pubnubConfig, jsonPluggableLibrary, pubnubUnit, log, tokenManager, instance)
Expand Down Expand Up @@ -76,6 +77,11 @@ public PublishFileMessageOperation FileName(string name)
this.currentFileName = name;
return this;
}
public PublishFileMessageOperation CustomMessageType(string customMessageType)
{
this.customMessageType = customMessageType;
return this;
}

public PublishFileMessageOperation QueryParam(Dictionary<string, object> customQueryParam)
{
Expand Down Expand Up @@ -250,6 +256,10 @@ private RequestParameter CreateRequestParameter()
if (!storeInHistory) {
requestQueryStringParams.Add("store", "0");
}

if (!string.IsNullOrEmpty(customMessageType)) {
requestQueryStringParams.Add("custom_message_type", customMessageType);
}

if (queryParam != null && queryParam.Count > 0) {
foreach (KeyValuePair<string, object> kvp in queryParam) {
Expand Down
45 changes: 30 additions & 15 deletions src/Api/PubnubApi/EndPoint/Files/SendFileOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class SendFileOperation : PubnubCoreBase
private bool storeInHistory = true;
private Dictionary<string, object> userMetadata;
private int ttl = -1;
private string customMessageType;

public SendFileOperation(PNConfiguration pubnubConfig, IJsonPluggableLibrary jsonPluggableLibrary, IPubnubUnitTest pubnubUnit, IPubnubLog log, TokenManager tokenManager, Pubnub instance) : base(pubnubConfig, jsonPluggableLibrary, pubnubUnit, log, tokenManager, instance)
{
Expand Down Expand Up @@ -67,6 +68,12 @@ public SendFileOperation Ttl(int ttl)
this.ttl = ttl;
return this;
}

public SendFileOperation CustomMessageType(string customMessageType)
{
this.customMessageType = customMessageType;
return this;
}

public SendFileOperation File(string fileNameWithFullPath)
{
Expand Down Expand Up @@ -180,11 +187,12 @@ private void ProcessFileUpload(PNCallback<PNFileUploadResult> callback)
int publishFileRetryLimit = config.FileMessagePublishRetryLimit;
int currentFileRetryCount = 0;
bool publishFailed;
PNStatus publishFileMessageStatus;
do {
currentFileRetryCount += 1;
PNResult<PNPublishFileMessageResult> publishFileMessageResponse = PublishFileMessage(publishPayload, queryParam).Result;
PNPublishFileMessageResult publishFileMessage = publishFileMessageResponse.Result;
PNStatus publishFileMessageStatus = publishFileMessageResponse.Status;
publishFileMessageStatus = publishFileMessageResponse.Status;
if (publishFileMessageStatus != null && !publishFileMessageStatus.Error && publishFileMessage != null) {
publishFailed = false;
PNFileUploadResult result = new PNFileUploadResult();
Expand All @@ -202,11 +210,11 @@ private void ProcessFileUpload(PNCallback<PNFileUploadResult> callback)
LoggingMethod.WriteToLog(pubnubLog, string.Format(CultureInfo.InvariantCulture, "DateTime {0} PublishFileMessage Failed. currentFileRetryCount={1}", DateTime.Now.ToString(CultureInfo.InvariantCulture), currentFileRetryCount), config.LogVerbosity);
}
}
while (publishFailed && currentFileRetryCount <= publishFileRetryLimit);
while (publishFailed && currentFileRetryCount <= publishFileRetryLimit && !(publishFileMessageStatus?.StatusCode != 400 || publishFileMessageStatus.StatusCode != 403));
} else {
int statusCode = PNStatusCodeHelper.GetHttpStatusCode(transportResponse.Error.Message);
PNStatusCategory category = PNStatusCategoryHelper.GetPNStatusCategory(statusCode, transportResponse.Error.Message);
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(PNOperationType.PNFileUploadOperation, category, requestState, statusCode, new PNException(transportResponse.Error.Message, transportResponse.Error));
int statusCode = PNStatusCodeHelper.GetHttpStatusCode(transportResponse?.Error?.Message);
PNStatusCategory category = PNStatusCategoryHelper.GetPNStatusCategory(statusCode, transportResponse?.Error?.Message);
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(PNOperationType.PNFileUploadOperation, category, requestState, statusCode, new PNException(transportResponse?.Error?.Message, transportResponse?.Error));
requestState.PubnubCallback.OnResponse(default, status);
}
}
Expand All @@ -229,11 +237,13 @@ private async Task<PNResult<PNFileUploadResult>> ProcessFileUpload()
return returnValue;
}
LoggingMethod.WriteToLog(pubnubLog, string.Format(CultureInfo.InvariantCulture, "DateTime {0} GenerateFileUploadUrl executed.", DateTime.Now.ToString(CultureInfo.InvariantCulture)), config.LogVerbosity);
RequestState<PNFileUploadResult> requestState = new RequestState<PNFileUploadResult>();
requestState.ResponseType = PNOperationType.PNFileUploadOperation;
requestState.Reconnect = false;
requestState.EndPointOperation = this;
requestState.UsePostMethod = true;
RequestState<PNFileUploadResult> requestState = new RequestState<PNFileUploadResult>
{
ResponseType = PNOperationType.PNFileUploadOperation,
Reconnect = false,
EndPointOperation = this,
UsePostMethod = true
};
byte[] sendFileByteArray = sendFileBytes ?? GetByteArrayFromFilePath(sendFileFullPath);
string dataBoundary = string.Format(CultureInfo.InvariantCulture, "----------{0:N}", Guid.NewGuid());
string contentType = "multipart/form-data; boundary=" + dataBoundary;
Expand Down Expand Up @@ -303,11 +313,12 @@ private async Task<PNResult<PNFileUploadResult>> ProcessFileUpload()
int publishFileRetryLimit = config.FileMessagePublishRetryLimit;
int currentFileRetryCount = 0;
bool publishFailed;
PNStatus publishFileMessageStatus;
do {
currentFileRetryCount += 1;
PNResult<PNPublishFileMessageResult> publishFileMessageResponse = await PublishFileMessage(publishPayload, queryParam).ConfigureAwait(false);
PNPublishFileMessageResult publishFileMessage = publishFileMessageResponse.Result;
PNStatus publishFileMessageStatus = publishFileMessageResponse.Status;
publishFileMessageStatus = publishFileMessageResponse.Status;
if (publishFileMessageStatus != null && !publishFileMessageStatus.Error && publishFileMessage != null) {
publishFailed = false;
PNFileUploadResult result = new PNFileUploadResult
Expand All @@ -326,7 +337,7 @@ private async Task<PNResult<PNFileUploadResult>> ProcessFileUpload()
await Task.Delay(1000);
}
}
while (publishFailed && currentFileRetryCount <= publishFileRetryLimit);
while (publishFailed && currentFileRetryCount <= publishFileRetryLimit && !(publishFileMessageStatus?.StatusCode != 400 || publishFileMessageStatus.StatusCode != 403));
}

return returnValue;
Expand Down Expand Up @@ -403,7 +414,7 @@ private async Task<PNResult<PNPublishFileMessageResult>> PublishFileMessage(obje
ResponseBuilder responseBuilder = new ResponseBuilder(config, jsonLibrary, pubnubLog);
PNPublishFileMessageResult publishResult = responseBuilder.JsonToObject<PNPublishFileMessageResult>(result, true);
StatusBuilder statusBuilder = new StatusBuilder(config, jsonLibrary);
if (publishResult != null) {
if (publishResult != null && transportResponse.StatusCode == Constants.HttpRequestSuccessStatusCode) {
returnValue.Result = publishResult;
PNStatus status = statusBuilder.CreateStatusResponse(requestState.ResponseType, PNStatusCategory.PNAcknowledgmentCategory, requestState, transportResponse.StatusCode, null);
returnValue.Status = status;
Expand Down Expand Up @@ -564,6 +575,10 @@ private RequestParameter CreatePublishFileMessageRequestParameter()
if (storeInHistory && ttl >= 0) {
requestQueryStringParams.Add("ttl", ttl.ToString(CultureInfo.InvariantCulture));
}

if (!string.IsNullOrEmpty(customMessageType)) {
requestQueryStringParams.Add("custom_message_type", customMessageType);
}

if (!storeInHistory) {
requestQueryStringParams.Add("store", "0");
Expand All @@ -587,8 +602,8 @@ private RequestParameter CreatePublishFileMessageRequestParameter()
private string PrepareContent(object originalMessage)
{
string message = jsonLibrary.SerializeToJsonString(originalMessage);
if (config.CryptoModule != null || config.CipherKey.Length > 0) {
config.CryptoModule ??= new CryptoModule(new LegacyCryptor(config.CipherKey, config.UseRandomInitializationVector, pubnubLog), null);
if (config.CryptoModule != null || config.CipherKey.Length > 0 || currentFileCipherKey != null) {
config.CryptoModule ??= new CryptoModule(new LegacyCryptor(currentFileCipherKey ?? config.CipherKey, config.UseRandomInitializationVector, pubnubLog), null);
string encryptMessage = config.CryptoModule.Encrypt(message);
message = jsonLibrary.SerializeToJsonString(encryptMessage);
}
Expand Down
15 changes: 11 additions & 4 deletions src/Api/PubnubApi/EndPoint/Objects/SetMembershipsOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,20 @@ private RequestParameter CreateRequestParameter()
Dictionary<string, object> messageEnvelope = new Dictionary<string, object>();
if (addMembership != null) {
List<Dictionary<string, object>> setMembershipFormatList = new List<Dictionary<string, object>>();
for (int index = 0; index < addMembership.Count; index++) {
foreach (var membership in addMembership)
{
Dictionary<string, object> currentMembershipFormat = new Dictionary<string, object>
{
{ "channel", new Dictionary<string, string> { { "id", addMembership[index].Channel } } }
{ "channel", new Dictionary<string, string> { { "id", membership.Channel } } }
};
if (addMembership[index].Custom != null) {
currentMembershipFormat.Add("custom", addMembership[index].Custom);
if (membership.Custom != null) {
currentMembershipFormat.Add("custom", membership.Custom);
}
if (membership.Status != null) {
currentMembershipFormat.Add("status", membership.Status);
}
if (membership.Type != null) {
currentMembershipFormat.Add("type", membership.Type);
}
setMembershipFormatList.Add(currentMembershipFormat);
}
Expand Down
Loading

0 comments on commit 59ba055

Please sign in to comment.