public JObject Process(byte[] syncDataBytes) { if (syncDataBytes == null) { throw new NullReferenceException(nameof(syncDataBytes)); } JObject jsonResult = JsonDefaultResponse(); SyncServerLockObject syncServerLockObject = null; bool lockTaken = false; List <string> log = new List <string>(); SyncEngine.PayloadAction payloadAction = SyncEngine.PayloadAction.Synchronize; SyncEngine.ApplyChangesResult applyChangesResult = null; SyncEngine.GetChangesResult getChangesResult = null; SyncEngine.GetKnowledgeResult getKnowledgeResult = null; SyncEngine.ApplyChangesByKnowledgeResult applyChangesByKnowledgeResult = null; SyncEngine.GetChangesByKnowledgeResult getChangesByKnowledgeResult = null; try { string json = SyncEngine.Decompress(syncDataBytes); JObject payload = JsonConvert.DeserializeObject <JObject>(json); string synchronizationId = payload[nameof(SyncEngine.BaseInfo.SynchronizationId)].Value <string>(); payloadAction = (SyncEngine.PayloadAction)Enum.Parse(typeof(SyncEngine.PayloadAction), payload[nameof(SyncEngine.BaseInfo.PayloadAction)].Value <string>()); lock (serverLock) { if (!serverLockObjects.ContainsKey(synchronizationId)) { SyncServerLockObject newLockObject = new SyncServerLockObject(synchronizationId); serverLockObjects.Add(synchronizationId, newLockObject); } syncServerLockObject = serverLockObjects[synchronizationId]; } Monitor.TryEnter(syncServerLockObject, 0, ref lockTaken); if (!lockTaken) { throw new Exception($"{nameof(SyncServerLockObject.SynchronizationId)}: {syncServerLockObject.SynchronizationId}, Synchronization process is already in progress"); } if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Synchronize) { SyncEngine.ApplyChangesParameter applyChangesParameter = SyncEngine.ApplyChangesParameter.FromPayload(payload); applyChangesParameter.Log = log; syncEngine.ApplyChanges(applyChangesParameter, ref applyChangesResult); } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { SyncEngine.GetChangesParameter getChangesParameter = SyncEngine.GetChangesParameter.FromPayload(payload, syncEngine); getChangesParameter.Log = log; syncEngine.GetChanges(getChangesParameter, ref getChangesResult); } else { throw new NotImplementedException(payloadAction.ToString()); } } else if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.DatabaseTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Knowledge) { SyncEngine.GetKnowledgeParameter getKnowledgeParameter = SyncEngine.GetKnowledgeParameter.FromPayload(payload); getKnowledgeParameter.Log = log; syncEngine.GetKnowledge(getKnowledgeParameter, ref getKnowledgeResult); } else if (payloadAction == SyncEngine.PayloadAction.Synchronize) { SyncEngine.ApplyChangesByKnowledgeParameter applyChangesByKnowledgeParameter = SyncEngine.ApplyChangesByKnowledgeParameter.FromPayload(payload); applyChangesByKnowledgeParameter.Log = log; syncEngine.ApplyChangesByKnowledge(applyChangesByKnowledgeParameter, ref applyChangesByKnowledgeResult); } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { SyncEngine.GetChangesByKnowledgeParameter getChangesByKnowledgeParameter = SyncEngine.GetChangesByKnowledgeParameter.FromPayload(payload); getChangesByKnowledgeParameter.Log = log; syncEngine.GetChangesByKnowledge(getChangesByKnowledgeParameter, ref getChangesByKnowledgeResult); } else { throw new NotImplementedException(payloadAction.ToString()); } } else { throw new NotImplementedException(syncEngine.SyncConfiguration.TimeStampStrategy.ToString()); } } catch (Exception e) { jsonResult["isOK"] = false; jsonResult["errorMessage"] = e.Message; log.Add(e.Message); } finally { if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Synchronize) { if (applyChangesResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(applyChangesResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in applyChangesResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { if (getChangesResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getChangesResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getChangesResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else { throw new NotImplementedException(payloadAction.ToString()); } } else if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.DatabaseTimeStamp) { if (payloadAction == SyncEngine.PayloadAction.Knowledge) { if (getKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.Synchronize) { if (applyChangesByKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(applyChangesByKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in applyChangesByKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else if (payloadAction == SyncEngine.PayloadAction.SynhronizeReverse) { if (getChangesByKnowledgeResult != null) { try { jsonResult["payload"] = Convert.ToBase64String(getChangesByKnowledgeResult.GetCompressed()); } catch (Exception e) { string errMsg = $"jsonResult payload in getChangesByKnowledgeResult Error: {e.Message}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } } } else { throw new NotImplementedException(payloadAction.ToString()); } } else { string errMsg = $"Process finally block Not Implemented Error: {syncEngine.SyncConfiguration.TimeStampStrategy.ToString()}"; jsonResult["isOK"] = false; jsonResult["errorMessage"] = errMsg; log.Add(errMsg); } jsonResult["log"] = JArray.FromObject(log); if (lockTaken) { Monitor.Exit(syncServerLockObject); } } return(jsonResult); }
private async Task SynchronizeGlobalTimeStamp(SynchronizationMethodEnum synchronizationMethod, Dictionary <string, object> customInfo, SyncResult syncResult) { if (synchronizationMethod != SynchronizationMethodEnum.PushThenPull) { throw new SyncEngineConstraintException($"{nameof(synchronizationMethod)} other than {SynchronizationMethodEnum.PushThenPull.ToString()} is not supported, because {nameof(SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp)} is already using Global DateTime (World Clock) as the time stamp, therefore, performing PushThenPull / PullThenPush will not have different effect (due to the same kind of time stamp being compared)"); } syncResult.Log.Add("=== Client Get Changes ==="); SyncEngine.GetChangesParameter clientGetChangesParameter = new SyncEngine.GetChangesParameter( SyncEngine.PayloadAction.Synchronize, synchronizationId, customInfo); clientGetChangesParameter.Log = syncResult.Log; clientGetChangesParameter.LastSync = syncEngine.InvokeGetClientLastSync(); SyncEngine.GetChangesResult clientGetChangesResult = null; try { syncEngine.GetChanges(clientGetChangesParameter, ref clientGetChangesResult); } catch (Exception) { throw; } finally { if (clientGetChangesResult != null) { syncResult.ClientLog.SentChanges.AddRange(clientGetChangesResult.LogChanges); } } syncResult.Log.Add("=== Server Apply Changes ==="); SyncEngine.ApplyChangesParameter serverApplyChangesParameter = new SyncEngine.ApplyChangesParameter( SyncEngine.PayloadAction.Synchronize, synchronizationId, customInfo); serverApplyChangesParameter.Changes = clientGetChangesResult.Changes; SyncEngine.ApplyChangesResult serverApplyChangesResult = null; (string serverApplyChangesErrMsg, JObject jObjectServerApplyChangesResult) = await ExecuteOnServer(serverApplyChangesParameter.GetCompressed(), syncResult); if (jObjectServerApplyChangesResult != null) { serverApplyChangesResult = SyncEngine.ApplyChangesResult.FromPayload(jObjectServerApplyChangesResult); syncResult.ServerLog.AppliedChanges.Inserts.AddRange(serverApplyChangesResult.Inserts); syncResult.ServerLog.AppliedChanges.Updates.AddRange(serverApplyChangesResult.Updates); syncResult.ServerLog.AppliedChanges.Deletes.AddRange(serverApplyChangesResult.Deletes); syncResult.ServerLog.AppliedChanges.Conflicts.AddRange(serverApplyChangesResult.Conflicts); } if (!string.IsNullOrEmpty(serverApplyChangesErrMsg)) { throw new Exception(serverApplyChangesErrMsg); } syncResult.Log.Add("=== Server Get Changes ==="); SyncEngine.GetChangesParameter serverGetChangesParameter = new SyncEngine.GetChangesParameter( SyncEngine.PayloadAction.SynhronizeReverse, synchronizationId, customInfo); serverGetChangesParameter.LastSync = clientGetChangesParameter.LastSync; serverGetChangesParameter.PayloadAppliedIds = serverApplyChangesResult.PayloadAppliedIds; SyncEngine.GetChangesResult serverGetChangesResult = null; (string serverGetChangesErrMsg, JObject jObjectServerGetChangesResult) = await ExecuteOnServer(serverGetChangesParameter.GetCompressed(), syncResult); if (jObjectServerGetChangesResult != null) { serverGetChangesResult = SyncEngine.GetChangesResult.FromPayload(jObjectServerGetChangesResult); syncResult.ServerLog.SentChanges.AddRange(serverGetChangesResult.LogChanges); } if (!string.IsNullOrEmpty(serverGetChangesErrMsg)) { throw new Exception(serverGetChangesErrMsg); } syncResult.Log.Add("=== Client Apply Changes ==="); SyncEngine.ApplyChangesParameter clientApplyChangesParameter = new SyncEngine.ApplyChangesParameter( SyncEngine.PayloadAction.Synchronize, synchronizationId, customInfo); clientApplyChangesParameter.Log = syncResult.Log; clientApplyChangesParameter.Changes = serverGetChangesResult.Changes; SyncEngine.ApplyChangesResult clientApplyChangesResult = null; try { syncEngine.ApplyChanges(clientApplyChangesParameter, ref clientApplyChangesResult); } catch (Exception) { throw; } finally { if (clientApplyChangesResult != null) { syncResult.ClientLog.AppliedChanges.Inserts.AddRange(clientApplyChangesResult.Inserts); syncResult.ClientLog.AppliedChanges.Updates.AddRange(clientApplyChangesResult.Updates); syncResult.ClientLog.AppliedChanges.Deletes.AddRange(clientApplyChangesResult.Deletes); syncResult.ClientLog.AppliedChanges.Conflicts.AddRange(clientApplyChangesResult.Conflicts); } } syncResult.Log.Add($"===LastSync from Client Get Changes Parameter: {clientGetChangesParameter.LastSync} ==="); syncResult.Log.Add($"===MaxTimeStamp from Client Get Changes Result: {clientGetChangesResult.MaxTimeStamp} ==="); syncResult.Log.Add($"===MaxTimeStamp from Server Get Changes Result: {serverGetChangesResult.MaxTimeStamp} ==="); long maxLastSync = clientGetChangesParameter.LastSync; if (clientGetChangesResult.MaxTimeStamp > maxLastSync) { maxLastSync = clientGetChangesResult.MaxTimeStamp; } if (serverGetChangesResult.MaxTimeStamp > maxLastSync) { maxLastSync = serverGetChangesResult.MaxTimeStamp; } syncResult.Log.Add($"=== LastSync Updated To: {maxLastSync} ==="); syncEngine.SetClientLastSync(maxLastSync); }