Esempio n. 1
0
        public async Task <SyncResult> SynchronizeAsync(SynchronizationMethodEnum synchronizationMethod = SynchronizationMethodEnum.PushThenPull, Dictionary <string, object> customInfo = null)
        {
            SyncResult syncResult = new SyncResult();

            try
            {
                syncResult.Log.Add($"=== Synchronize Started ===");

                if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.GlobalTimeStamp)
                {
                    await SynchronizeGlobalTimeStamp(synchronizationMethod, customInfo, syncResult);
                }
                else if (syncEngine.SyncConfiguration.TimeStampStrategy == SyncConfiguration.TimeStampStrategyEnum.DatabaseTimeStamp)
                {
                    await SynchronizeDatabaseTimeStamp(synchronizationMethod, customInfo, syncResult);
                }
                else
                {
                    throw new NotImplementedException(syncEngine.SyncConfiguration.TimeStampStrategy.ToString());
                }

                syncResult.Log.Add($"=== Synchronize Finished ===");
            }
            catch (Exception e)
            {
                syncResult.ErrorMessage = e.Message;
                syncResult.Log.Add($"=== Error: {e.Message} ===");
            }
            return(syncResult);
        }
Esempio n. 2
0
        private async Task SynchronizeDatabaseTimeStampOneWay(bool runOnClient, Dictionary <string, object> customInfo, SyncResult syncResult)
        {
            string localName  = null;
            string remoteName = null;

            SyncEngine.PayloadAction payloadAction = SyncEngine.PayloadAction.Synchronize;
            if (runOnClient)
            {
                localName     = "Client";
                remoteName    = "Server";
                payloadAction = SyncEngine.PayloadAction.Synchronize;
            }
            else
            {
                localName     = "Server";
                remoteName    = "Client";
                payloadAction = SyncEngine.PayloadAction.SynhronizeReverse;
            }

            syncResult.Log.Add($"=== {localName} Get Knowledge (As Local Knowledge) ===");
            SyncEngine.GetKnowledgeParameter localGetKnowledgeParameter = new SyncEngine.GetKnowledgeParameter(
                SyncEngine.PayloadAction.Knowledge,
                synchronizationId,
                customInfo);
            if (runOnClient)
            {
                localGetKnowledgeParameter.Log = syncResult.Log;
            }
            SyncEngine.GetKnowledgeResult localGetKnowledgeResult = null;
            if (runOnClient)
            {
                try
                {
                    syncEngine.GetKnowledge(localGetKnowledgeParameter, ref localGetKnowledgeResult);
                }
                catch (Exception)
                {
                    throw;
                }
            }
            else
            {
                (string localGetKnowledgeErrMsg, JObject jObjectLocalGetKnowledgeResult) = await ExecuteOnServer(localGetKnowledgeParameter.GetCompressed(), syncResult);

                if (jObjectLocalGetKnowledgeResult != null)
                {
                    localGetKnowledgeResult = SyncEngine.GetKnowledgeResult.FromPayload(jObjectLocalGetKnowledgeResult);
                }
                if (!string.IsNullOrEmpty(localGetKnowledgeErrMsg))
                {
                    throw new Exception(localGetKnowledgeErrMsg);
                }
            }

            syncResult.Log.Add($"=== {remoteName} Get Knowledge (As Remote Knowledge) ===");
            SyncEngine.GetKnowledgeParameter remoteGetKnowledgeParameter = new SyncEngine.GetKnowledgeParameter(
                SyncEngine.PayloadAction.Knowledge,
                synchronizationId,
                customInfo);
            if (!runOnClient)
            {
                remoteGetKnowledgeParameter.Log = syncResult.Log;
            }
            SyncEngine.GetKnowledgeResult remoteGetKnowledgeResult = null;
            if (runOnClient)
            {
                (string remoteGetKnowledgeErrMsg, JObject jObjectRemoteGetKnowledgeResult) = await ExecuteOnServer(remoteGetKnowledgeParameter.GetCompressed(), syncResult);

                if (jObjectRemoteGetKnowledgeResult != null)
                {
                    remoteGetKnowledgeResult = SyncEngine.GetKnowledgeResult.FromPayload(jObjectRemoteGetKnowledgeResult);
                }
                if (!string.IsNullOrEmpty(remoteGetKnowledgeErrMsg))
                {
                    throw new Exception(remoteGetKnowledgeErrMsg);
                }
            }
            else
            {
                try
                {
                    syncEngine.GetKnowledge(remoteGetKnowledgeParameter, ref remoteGetKnowledgeResult);
                }
                catch (Exception)
                {
                    throw;
                }
            }

            syncResult.Log.Add($"=== {localName} Get Changes based on {remoteName} Knowledge ===");
            SyncEngine.GetChangesByKnowledgeParameter getChangesByKnowledgeParameter = new SyncEngine.GetChangesByKnowledgeParameter(
                payloadAction,
                synchronizationId,
                customInfo);
            if (runOnClient)
            {
                getChangesByKnowledgeParameter.Log = syncResult.Log;
            }
            getChangesByKnowledgeParameter.LocalKnowledgeInfos  = localGetKnowledgeResult.KnowledgeInfos;
            getChangesByKnowledgeParameter.RemoteKnowledgeInfos = remoteGetKnowledgeResult.KnowledgeInfos;
            SyncEngine.GetChangesByKnowledgeResult getChangesByKnowledgeResult = null;
            if (runOnClient)
            {
                try
                {
                    syncEngine.GetChangesByKnowledge(getChangesByKnowledgeParameter, ref getChangesByKnowledgeResult);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (getChangesByKnowledgeResult != null)
                    {
                        syncResult.ClientLog.SentChanges.AddRange(getChangesByKnowledgeResult.LogChanges);
                    }
                }
            }
            else
            {
                (string getChangesByKnowledgeErrMsg, JObject jObjectGetChangesByKnowledgeResult) = await ExecuteOnServer(getChangesByKnowledgeParameter.GetCompressed(), syncResult);

                if (jObjectGetChangesByKnowledgeResult != null)
                {
                    getChangesByKnowledgeResult = SyncEngine.GetChangesByKnowledgeResult.FromPayload(jObjectGetChangesByKnowledgeResult);
                    syncResult.ServerLog.SentChanges.AddRange(getChangesByKnowledgeResult.LogChanges);
                }
                if (!string.IsNullOrEmpty(getChangesByKnowledgeErrMsg))
                {
                    throw new Exception(getChangesByKnowledgeErrMsg);
                }
            }

            syncResult.Log.Add($"=== {remoteName} Apply Changes ===");
            SyncEngine.ApplyChangesByKnowledgeParameter applyChangesByKnowledgeParameter = new SyncEngine.ApplyChangesByKnowledgeParameter(
                payloadAction,
                synchronizationId,
                customInfo);
            if (!runOnClient)
            {
                applyChangesByKnowledgeParameter.Log = syncResult.Log;
            }
            applyChangesByKnowledgeParameter.Changes = getChangesByKnowledgeResult.Changes;
            applyChangesByKnowledgeParameter.SourceDatabaseInstanceId      = localGetKnowledgeResult.KnowledgeInfos.Where(w => w.IsLocal).First().DatabaseInstanceId;
            applyChangesByKnowledgeParameter.DestinationDatabaseInstanceId = remoteGetKnowledgeResult.KnowledgeInfos.Where(w => w.IsLocal).First().DatabaseInstanceId;
            SyncEngine.ApplyChangesByKnowledgeResult applyChangesByKnowledgeResult = null;
            if (runOnClient)
            {
                (string applyChangesByKnowledgeErrMsg, JObject jObjectApplyChangesByKnowledgeResult) = await ExecuteOnServer(applyChangesByKnowledgeParameter.GetCompressed(), syncResult);

                if (jObjectApplyChangesByKnowledgeResult != null)
                {
                    applyChangesByKnowledgeResult = SyncEngine.ApplyChangesByKnowledgeResult.FromPayload(jObjectApplyChangesByKnowledgeResult);
                    syncResult.ServerLog.AppliedChanges.Inserts.AddRange(applyChangesByKnowledgeResult.Inserts);
                    syncResult.ServerLog.AppliedChanges.Updates.AddRange(applyChangesByKnowledgeResult.Updates);
                    syncResult.ServerLog.AppliedChanges.Deletes.AddRange(applyChangesByKnowledgeResult.Deletes);
                    syncResult.ServerLog.AppliedChanges.Conflicts.AddRange(applyChangesByKnowledgeResult.Conflicts);
                }
                if (!string.IsNullOrEmpty(applyChangesByKnowledgeErrMsg))
                {
                    throw new Exception(applyChangesByKnowledgeErrMsg);
                }
            }
            else
            {
                try
                {
                    syncEngine.ApplyChangesByKnowledge(applyChangesByKnowledgeParameter, ref applyChangesByKnowledgeResult);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (applyChangesByKnowledgeResult != null)
                    {
                        syncResult.ClientLog.AppliedChanges.Inserts.AddRange(applyChangesByKnowledgeResult.Inserts);
                        syncResult.ClientLog.AppliedChanges.Updates.AddRange(applyChangesByKnowledgeResult.Updates);
                        syncResult.ClientLog.AppliedChanges.Deletes.AddRange(applyChangesByKnowledgeResult.Deletes);
                        syncResult.ClientLog.AppliedChanges.Conflicts.AddRange(applyChangesByKnowledgeResult.Conflicts);
                    }
                }
            }
        }
Esempio n. 3
0
 private async Task SynchronizeDatabaseTimeStamp(SynchronizationMethodEnum synchronizationMethod, Dictionary <string, object> customInfo, SyncResult syncResult)
 {
     if (synchronizationMethod == SynchronizationMethodEnum.PushThenPull)
     {
         await SynchronizeDatabaseTimeStampOneWay(true, customInfo, syncResult);
         await SynchronizeDatabaseTimeStampOneWay(false, customInfo, syncResult);
     }
     else if (synchronizationMethod == SynchronizationMethodEnum.PullThenPush)
     {
         await SynchronizeDatabaseTimeStampOneWay(false, customInfo, syncResult);
         await SynchronizeDatabaseTimeStampOneWay(true, customInfo, syncResult);
     }
     else
     {
         throw new NotImplementedException(synchronizationMethod.ToString());
     }
 }
Esempio n. 4
0
        private async Task <(string errorMessage, JObject payload)> ExecuteOnServer(byte[] compressed, SyncResult syncResult)
        {
            JObject payload = null;

            using (var httpClient = new HttpClient())
            {
                if (httpHeaders != null)
                {
                    httpHeaders.ToList().ForEach(kvp =>
                    {
                        if (httpClient.DefaultRequestHeaders.Contains(kvp.Key))
                        {
                            httpClient.DefaultRequestHeaders.Remove(kvp.Key);
                        }
                        httpClient.DefaultRequestHeaders.Add(kvp.Key, kvp.Value);
                    });
                }

                using (var multipartFormDataContent = new MultipartFormDataContent())
                {
                    ByteArrayContent byteArrayContent = new ByteArrayContent(compressed);
                    multipartFormDataContent.Add(byteArrayContent, "files", "compressed.data");
                    var response = await httpClient.PostAsync(serverUrl, multipartFormDataContent);

                    if (response.IsSuccessStatusCode)
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();

                        JObject jObjectResponse = null;
                        try
                        {
                            jObjectResponse = JsonConvert.DeserializeObject <JObject>(responseContent);
                        }
                        catch (Exception eInner)
                        {
                            return($"Unable to parse Response as JObject: {eInner.Message}. Response: {responseContent}", payload);
                        }
                        List <string> serverLog = jObjectResponse["log"].ToObject <List <string> >();
                        for (int i = 0; i < serverLog.Count; i++)
                        {
                            syncResult.Log.Add($"Server -> {serverLog[i]}");
                        }
                        if (jObjectResponse.ContainsKey("payload"))
                        {
                            byte[] compressedResponse = Convert.FromBase64String(jObjectResponse["payload"].Value <string>());
                            string jsonResponse       = SyncEngine.Decompress(compressedResponse);
                            payload = JsonConvert.DeserializeObject <JObject>(jsonResponse);
                        }
                        if (jObjectResponse.ContainsKey("errorMessage"))
                        {
                            return($"ServerMessage: {jObjectResponse["errorMessage"].Value<string>()}", payload);
                        }
                        return(null, payload);
                    }
                    else
                    {
                        return($"Response StatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}", payload);
                    }
                }
            }
        }
Esempio n. 5
0
        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);
        }