예제 #1
0
 public SyncClient(string synchronizationId, SyncEngine syncEngine, string serverUrl, Dictionary <string, string> httpHeaders)
 {
     this.synchronizationId = synchronizationId ?? throw new NullReferenceException(nameof(synchronizationId));
     this.syncEngine        = syncEngine ?? throw new NullReferenceException(nameof(syncEngine));
     this.serverUrl         = serverUrl ?? throw new NullReferenceException(nameof(serverUrl));
     this.httpHeaders       = httpHeaders;
 }
예제 #2
0
            public static GetChangesParameter FromPayload(JObject payload, SyncEngine syncEngine)
            {
                string synchronizationId = payload[nameof(SynchronizationId)].Value <string>();
                Dictionary <string, object> customInfo = payload[nameof(CustomInfo)].ToObject <Dictionary <string, object> >();
                PayloadAction       payloadAction      = (PayloadAction)Enum.Parse(typeof(PayloadAction), payload[nameof(PayloadAction)].Value <string>());
                GetChangesParameter parameter          = new GetChangesParameter(payloadAction, synchronizationId, customInfo);

                parameter.LastSync   = payload[nameof(LastSync)].Value <long>();
                parameter.AppliedIds = PayloadHelper.GetAppliedIdsFromPayload(payload[nameof(PayloadAppliedIds)].ToObject <Dictionary <string, List <object> > >(), syncEngine, synchronizationId, customInfo);
                return(parameter);
            }
예제 #3
0
        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);
        }
예제 #4
0
 public SyncServer(SyncEngine syncEngine)
 {
     this.syncEngine = syncEngine;
 }
예제 #5
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);
                    }
                }
            }
        }
예제 #6
0
 public SyncClient(string synchronizationId, SyncEngine syncEngine, string serverUrl)
     : this(synchronizationId, syncEngine, serverUrl, null)
 {
 }
예제 #7
0
            public static Dictionary <Type, List <object> > GetAppliedIdsFromPayload(Dictionary <string, List <object> > safeAppliedIds, SyncEngine syncEngine, string synchronizationId, Dictionary <string, object> customInfo)
            {
                Dictionary <Type, List <object> > result = new Dictionary <Type, List <object> >();

                foreach (var item in safeAppliedIds)
                {
                    string fullName  = UnsafeFullName(item.Key);
                    Type   localType = syncEngine.SyncConfiguration.SyncTypes.Where(w => w.FullName == fullName).FirstOrDefault();
                    if (localType == null)
                    {
                        throw new SyncEngineConstraintException($"Missing localType: {fullName} from AppliedIds");
                    }
                    if (!result.ContainsKey(localType))
                    {
                        result[localType] = new List <object>();
                    }
                    for (int i = 0; i < item.Value.Count; i++)
                    {
                        JValue value   = new JValue(item.Value[i]);
                        object localId = syncEngine.TransformIdType(localType, value, null, OperationType.GetChanges, synchronizationId, customInfo);
                        result[localType].Add(localId);
                    }
                }
                return(result);
            }